This lesson closes out lists with searching, sorting, and the functional-style listMap, listFilter, and listReduce โ plus one distinction that trips up almost everyone at least once: listFind vs. listContains.
Learning Objectives
After completing this lesson, you'll be able to:
- Explain the real difference between listFind and listContains.
- Sort a list's elements.
- Change a list's delimiter, or wrap elements in a qualifier string.
- Remove duplicate values from a list.
- Transform a list with listMap, listFilter, and listReduce.
listFind vs. listContains โ The Real Difference
These sound similar but do genuinely different things. listFind looks for an element that exactly matches your value. listContains looks for an element that merely contains your value as a substring, anywhere inside it.
listFind(cities, "Bang") returns 0 โ no element is exactly "Bang". listContains(cities, "Bang") returns 2 โ Bangkok contains "Bang" as a substring. Mixing these up is one of the most common list mistakes.
Counting Occurrences: listValueCount
Sorting a List
Without "numeric", a plain text sort would put "100" before "2", since it compares character by character.
Changing the Delimiter: listChangeDelims
Wrapping Elements: listQualify
Wraps every element in a qualifier string โ useful when building a SQL IN clause from a list of values.
Removing Duplicates
Functional Transforms: listMap, listFilter, listReduce
These work the same way as their array and struct equivalents โ a closure runs against every element. listMap's callback receives (item, index, list).
Real-World Example: Building a SQL IN Clause
In real code, prefer parameterized queries (<cfqueryparam> with a list) over building raw SQL strings like this โ this example is just to illustrate listQualify's purpose.
Common Beginner Mistakes
Using listContains when an exact match was intended
listContains("1,10,100", "1") returns 1 (matches the first element, since "1" is a substring of both "1" and "10" and "100") โ if you wanted exactly the element "1", use listFind instead.
Sorting numbers as text
listSort("2,10,1") without specifying "numeric" sorts as text, producing "1,10,2" โ alphabetical, not numerical order.
Forgetting listQualify wraps every element, not just the whole list
listQualify("1,2,3", "'") produces '1','2','3' โ the qualifier goes around each individual element, not around the entire string.
Best Practices
- Reach for listFind when you need an exact match, listContains only when a partial/substring match is genuinely what you want.
- Always specify "numeric" explicitly when sorting a list of numbers.
- Prefer parameterized queries over listQualify + manual SQL string building for anything touching a database.
Interview Questions
What's the real difference between listFind and listContains?
listFind matches an element that exactly equals your search value. listContains matches an element that merely contains your search value as a substring anywhere inside it.
Why might listSort("2,10,1") return an unexpected order?
Without specifying "numeric" as the sort type, it sorts as text, comparing character by character โ producing "1,10,2" instead of numerical order.
What does listQualify do?
It wraps every element in the list with a given qualifier string, commonly used to prepare values for a SQL IN clause.
Summary
In this lesson, you learned the crucial difference between listFind (exact match) and listContains (substring match), how to sort lists correctly, change delimiters, qualify elements, remove duplicates, and use the functional listMap, listFilter, and listReduce.
This wraps up lists for this module.
What's Next?
The next lesson covers Queries โ working with database result sets in ColdFusion.