Struct Iteration With CFLoop Includes Super Intuitive Aliases In Lucee CFML 5.3.6.61
A few months ago, I was excited to discover that CFLoop
exposes both keys and values during Struct iteration in Lucee CFML. In that post, I demonstrated that the "key" could be accessed via index
and the "value" could be accessed via item
. Well, life just keeps getting better! Earlier this week, I discovered (in the Lucee documentation) that the CFLoop
tag has even more intuitive aliases for Struct iteration! I'm not sure how I missed this before; but, apparently you can now use key
, value
, and struct
in Lucee CFML 5.3.6.61.
To see this in action, I've defined a Struct and am going to loop over it using three different methods:
- The old-school
item
approach. - The newer
index
anditem
approach. - The awesome
key
,value
, andstruct
approach.
Not that I am using the Elvis operator to manage null value references in the following code:
<cfscript>
data = [
id: 1,
name: "Yoga Socks",
sku: "t-12345-yogasocks",
price: 14.95,
weight: 194,
createdAt: now(),
deletedAt: nullValue()
];
// Traditional Struct iteration in ColdFusion only exposed the "item", which was the
// key being accessed. It was then up to the iteration body to access the "value"
// using the iteration key.
loop
item = "key"
collection = data
{
value = ( data[ key ] ?: "undefined" );
echo( "#key# : #value# <br />" );
}
echo( "<hr />" );
// Then, Lucee CFML added the ability to define both the "index" and the "item"
// during Struct iteration wherein the "index" was the "key" and the "item" was the
// key-value.
loop
index = "key"
item = "value"
collection = data
{
echo( "#key# : #( value ?: 'undefined' )# <br />" );
}
echo( "<hr />" );
// BUT, I just discovered (from reading the documentation) that Lucee CFML actually
// has really helpful aliases for Struct iteration components, making them much
// easier to write and read:
// --
// * Struct instead of Collection.
// * Key instead of Index.
// * Value instead of Item.
loop
key = "key"
value = "value"
struct = data
{
echo( "#key# : #( value ?: 'undefined' )# <br />" );
}
</cfscript>
As you can see, the last CFLoop
tag uses key
, value
, and struct
for Struct iteration. Super intuitive! And, when we run the above ColdFusion code, we get the following output:
How cool is that! It feels like with every passing day, I find yet another reason to love Lucee CFML! This language just keeps getting more and more world-class.
.each()
Epilogue on Lucee CFML is so freaking flexible. And, because I am sure there are people who will look at me "using tags in script" and begrudge it, it's worth mentioning that you can always use the .each()
iteration method to expose all the same data-points:
<cfscript>
data = [
id: 1,
name: "Yoga Socks",
sku: "t-12345-yogasocks",
price: 14.95,
weight: 194,
createdAt: now(),
deletedAt: nullValue()
];
data.each(
( key, value, collection ) => {
echo( "#key# : #( value ?: 'undefined' )# <br />" );
}
);
</cfscript>
I use both approaches, depending on the situation. One nice thing about using the CFLoop
tag directly in CFScript is that - according to Gert Franz - using the tag is actually faster than the Function-based iteration. A micro-optimization to be sure; but, it's good to have in the back of your mind.
Of course, another benefit of using Function-based iteration is that you have the option to leverage parallel iteration using asynchronous threads in Lucee CFML, which is all flavors of awesome for high-latency actions.
Want to use code from this post? Check out the license.
Reader Comments
Ben, your last example also shows the beauty and simplicity of arrow functions , which suits perfectly for these iterations. For such a long time it hurt me trying to understand arrow functions, but these cases shows exactly why they've been made. Thanks for the blog post.
@Andreas,
Totally agreed. I've been using the
.map()
and.filter()
functions a lot more lately in my programming. It's been really enjoyable; and I think is easy enough to follow / has good readability.