Ask a Jedi: List question

This post is more than 2 years old.

Kyle asks:

I have a scheduling portion of my site, which allows the user to select a start time and duration (maximum of 2 hours) for a meeting. Here is a sample of the code to determine time slots that are available:

<cfset timeTaken = "8.5,9,9.5,10,12,12.5,15.5">
<cfset time ="8,8.5,9,9.5,10,10.5,11,11.5,12,12.5,13,13.5,14,14.5,15,15.5,16"> <cfset availTime = "">
<cfset notAvail = "">

<cfloop list="#time#" index="t">
<cfif not listContains(timeTaken,t)>

<cfset availTime = listAppend(availTime,t)>

<cfset notAvail = listAppend(notAvail, t)>

Time: #time# <p>
Time Taken: #timeTaken# <p>
Available Time: #availTime# <p>
Not Available: #notAvail#

There is a simple example to show you my problem. For some reason, 8 and 15 are not found in the loop so therefore are classified as not available, even though they are. Should I be using another list function instead of not listContains() ?

You know that saying about gut instincts? You were right. listContains is indeed the issue. ListContains will tell you if any of the list items contains your match, but you want a full match. If you switch to listFind (or listFindNoCase), your problem goes away. Frankly, I have yet to see a good need for listContains, and every code block I've seen using it really wanted listFind instead!

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA

Archived Comments

Comment 1 by Jason Brookins posted on 3/12/2008 at 11:06 PM

Man, this is right on target. I can't tell you how many times early in my CF coding career I had to remind myself to use listfind() instead of listcontains().

And, maybe this is senility creeping in, but I still have to remind myself from time to time.

Comment 2 by Raul Riera posted on 3/12/2008 at 11:27 PM

You know what I hate about lists, you cant use listAppend on an empty list (in order to create one from stracth dynamctly). I always end up making arrays.

Comment 3 by Raymond Camden posted on 3/12/2008 at 11:48 PM

@Rual: Eh? Of course you can.

<cfset l = "">
<cfoutput>#listAppend(l, "Ray")#</cfoutput>

That works just fine. The empty string is a list of 0 items, so it adds it as the first item.

Comment 4 by zac spitzer posted on 3/13/2008 at 4:28 AM

I love lists in CF, but i do tend to always fall back on structs because they are faster and more flexible

Comment 5 by Raul Riera posted on 3/16/2008 at 2:32 AM

I dont know why you always use RUAL as my name lol, but no that doesnt work

<cfset l = "">
<cfset listAppend(l, "Ray")>
<cfset listAppend(l, "Ray 2")>

Displays an empty string, that exact same example with an array works. In order to make it work I need to do this

<cfset l = "">
<cfset l = listAppend(l, "Ray")>
<cfset l = listAppend(l, "Ray 2")>

Comment 6 by Raymond Camden posted on 3/16/2008 at 5:53 AM

Because you did it wrong. listAppend _returns_ the list. It doesn't operate on it. You need to _save_ it.

<cfset l = listAppend(l, "Ray")>

It is different from array funcs, per the docs. :)

Comment 7 by Raul Riera posted on 3/16/2008 at 6:12 AM

Yeah, but I dont see the "sense" in that function, it should be operating on the list, why would I want to append something to it and not have it saved automactly? (if the array does the same thing) they shouldnt be named exactly the same (my opinion tough)

Comment 8 by Raymond Camden posted on 3/16/2008 at 5:43 PM

Heh, well, opinion or not - you had said that you can't use listAppend on an empty list - which isn't true. I get you may not like that it doesn't work the same as arrayAppend, but - it _does_ work.

To be honest - I encounter FAR more developers who get tripped up by how arrayAppend works.

Comment 9 by Raul Riera posted on 3/16/2008 at 7:52 PM

fair enough :)