Skip to main content
Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.

Struct Iteration With CFLoop Includes Super Intuitive Aliases In Lucee CFML 5.3.6.61

By Ben Nadel on
Tags: ColdFusion

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:

  1. The old-school item approach.
  2. The newer index and item approach.
  3. The awesome key, value, and struct 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:

Struct iteration performed three different ways in Lucee CFML.

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.

Epilogue on .each()

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.



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.

Reply to this Comment

@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.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Blog
Live in the Now
Oops!
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.