G'day:
I hope Salted (/Ross) and Ryan don't mind me pinching our IRC conversation for a blog article, but... well... too bad if they do. It's done now. This is it.
Ross was asking "whats the most efficient way to remove the first two items in a list and get back the remainder", which made my eyes narrow and decide there's probably something to get to the bottom of here. Because he mentioned "lists". And these should - in general - be avoided in CFML.
After some back and forth with Ryan, Ross settled on:
listtoarray(foo," "), arrayslice(bar,3), arraytolist(bar," ")
(pseudo code, obviously).
Now... I think lists are overused in CFML, and - indeed - they are a bit rubbish. Having a string of data and then using one character (OK, or "some characters ~") from the string as a delimiter is seldom going to work, especially with the default delimiter of comma. Because in really a lot of situations, commas are actually part of the data. And same with any other char-based delimiter (except say characters specifically intended to be delimiters like characters 28-31 (file, group record and unit separators, respectively). I really don't think lists should generally be part of a solution to anything.
With this in mind, I decided to check what was going on. This is copy-and-pasted from the IRC log (spelling and formatting addressed, otherwise it's unabridged):
16:36 <adam_cameron> Salted: first question that should be asked... why is it a list in the first place? Do you have any control over it?
16:36 <Salted> no, it's returned from a postcode lookup service
16:36 <Salted> I'm fairly certain that the address string will always have the postcode first so [p1] [pt2] [line1]
16:37 <Salted> it's not a list its a string but I'm treating it as a space delimited list for these purposes...
16:37 <adam_cameron> so it's a string? Not a list per se?
16:37 <adam_cameron> ok
16:37 <Salted> indeed
16:37 <adam_cameron> So what you actually want is everything after the second space?
16:37 <Salted> essentially yes
16:37 <adam_cameron> Not a list with the first two elements dropped off
16:37 <Salted> in this instance what you've mentioned is one and the same, if I treat it as a list
16:38 <adam_cameron> well literally, yes. However once you start treating it as a list, you're thinking about it wrong
16:39 <Salted> I don't see how thats different from thinking of strings as char arrays, for example
16:40 <Salted> "my name is ross" is both a char array of 14 elements and a list of 4 elements
16:40 <adam_cameron> because you start trying to use list functions on it
16:40 <adam_cameron> Which makes your code shit
My point here - one that Ross doesn't entirely agree with - is that just because one
can use a string as a list, doesn't mean - semantically - it
is a list. And one should try to keep one's code as semantically clear as possible.
What Ross has here is
not a space-separated list. Later in the conversation I extracted form him what the actual data was like, and this was a sample:
X1 2YZ Apartment 1903, 10 Random Street Suburbia, OURTOWN
What we have here is... a mess. It can be assessed in a number of ways:
- a post code part followed by an address part
- a post code followed by a street address followed by a city
- a post code followed by the street part of the address, the suburb part of the address, and the city part of the address
But what it
isn't is a space- (or comma-, or anything-) separated list. So one should not solve this problem using lists.
One should look at the actual requirement, and solve that.