Ask a Jedi: Finding an value in an array of structures

David asked an interesting question about searching an array of structures:

I've got a challenge for you. I have a single dimension array, and in each dimension is a structure. I need to find the array index of a value within the structure. So if I need to find the index where name is "pam", I would do the following:

<cfset myArray = arrayNew(1)> <cfset myArray[1]['name'] = "david"> <cfset myArray[1]['age'] = '35'> <cfset myArray[2]['name'] = "bob"> <cfset myArray[2]['age'] = '44'> <cfset myArray[3]['name'] = "pam"> <cfset myArray[3]['age'] = '42'>

<cfloop from=”1” to=”#arrayLen(myArray)#” index=”i”> <cfif structFind(myArray[i],’name’) IS ‘pam’> <cfset dimensionNumber = i> </cfif> </cfloop> </code>

I was wondering if there was a way to use java's indexOf function (myArray.indexOf('pam')) to achieve the same thing. I've haven't found the correct syntax but I thought that since indexOf only works on single dimension arrays, perhaps there was a way.

Actually, there is a simple solution if you don’t mind modifying your data a tiny bit. ColdFusion comes with a structFindValue() function. This function will search through a structure, no matter how complex, and find matches based on value. (There is a structFindKey as well.)

The problem though is that David’s data is an array at the top level. Luckily though we can change this real quick:

<cfset s = structNew()> <cfset s.myArray = myArray>

Once we have a structure, we can then just search it:

<cfset match = structFindValue(s, "pam", "all")> <cfdump var="#match#">

Match will contain all the possible matches where the value is name.

There is one problem though. This function will find all (or one) match based on the value. David wanted to search just names. If you look at the result above though you will see that it does contain the key. All in all though - David’s original solution is quicker and probably even simpler, if you know the exact path where you want to search. (Although I wouldn’t use structFind. See this post for a discussion why.)

As an interesting aside - don’t forget that the Variables scope is a struct as well. I didn’t have to copy myArray to a struct, I could have done this as well:

<cfset match = structFindValue(variables, "pam", "all")> <cfdump var="#match#">

You could, in theory, use this to search all your variables for a particular value. I’m not quite sure why you would do this - but it’s cool nonetheless.

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless 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 https://www.raymondcamden.com

Comments