Reputation: 13730
I have a semi-large (hundreds of records) 1-dimensional array in ColdFusion. Each item in the array is a struct with several properties. I want to search the array for a struct that has a specific "name" property. I know that for an array of string values I could use Java methods like so:
<cfset arrayIndex = myArray.indexOf("WhatImLookingFor") + 1>
...but that won't work for an array of structs. I also know I could brute-force it like this:
<cfset arrayIndex = 0>
<cfloop from="1" to="#ArrayLen(myArray)#" index="counter">
<cfif myArray[counter].name IS "WhatImLookingFor">
<cfset arrayIndex = counter>
</cfif>
</cfloop>
...but I feel like there must be a more efficient way. Does anyone have a better solution than this? You can assume that the "name" property is present in every struct and there are no gaps or other objects in the array.
Upvotes: 15
Views: 15029
Reputation: 1951
In CF 10 or Railo 4, you can use:
arrayIndex = ArrayFind(arrayOfStructs, function(struct){
return struct.name == "WhatImLookingFor";
});
It is not documented, but it works! ArrayFindAll() is also an option if you want all of the indices.
Upvotes: 10
Reputation: 7778
Unless you have a hash table you're creating as you build the array, I don't see how you're going to create a search function that is faster than the O(n) solution you've posted. Anyway, while you are building your arrays, you could do something like this:
<cfloop query="qryValues">
<cfset nameValues[name] = currentrow />
<cfset myArray[currentrow].name = name />
</cfloop>
<cfset arrayIndex = nameValues["WhatImLookingFor"] />
This assumes that the value always exists. You may need to check StructKeyExists(nameValues, "WhatImLookingFor") before making the call.
Upvotes: 12
Reputation: 32905
CFGroovy FTW! :)
<cfset count = 0>
<g:script>
count = myArray.find({
it["NAME"] == "WhatImLookingFor" }
})
</g:script>
or.. if you like a more java style (w/o closure)
<cfset count = 0>
<g:script>
for (i in myArray) {
if( i["NAME"] == "WhatImLookingFor" )
count++
}
</g:script>
Upvotes: 0
Reputation: 6639
Without looking at it too deeply, I would consider converting the structure to a query (below) and then doing do a query of a query.. assuming your dataset isn't too huge!
http://www.bennadel.com/blog/264-Ask-Ben-Converting-A-Struct-To-A-Query-And-More-Java-.htm
Do share what you ended up doing!
Edit: The StructFindValue suggested looks to be excellent as well, I didn't think to look up any relevant functions.
Upvotes: 1