ColdFusion - 如何高效地搜索一个结构数组?

15

我在ColdFusion中有一个较大的(数百条记录)一维数组。数组中的每个项都是一个带有几个属性的结构体。我想要搜索该数组,以找到具有特定“name”属性的结构体。对于一个字符串值的数组,我知道可以使用Java方法进行搜索:

<cfset arrayIndex = myArray.indexOf("WhatImLookingFor") + 1>

...但是这对于结构体数组是行不通的。我也知道我可以像这样进行暴力计算:

<cfset arrayIndex = 0>
<cfloop from="1" to="#ArrayLen(myArray)#" index="counter">
    <cfif myArray[counter].name IS "WhatImLookingFor">
        <cfset arrayIndex = counter>
    </cfif>
</cfloop>

...但是我感觉一定有更有效率的方法。有人比这个方法更好的解决方案吗?您可以假设每个结构体中都存在“name”属性,并且数组中没有间隙或其他对象。

5个回答

12

除非你在构建数组时创建了哈希表,否则我不认为你能创建比你发布的O(n)解决方案更快的搜索函数。无论如何,在构建数组时,你可以像这样做:

<cfloop query="qryValues">
    <cfset nameValues[name] = currentrow />
    <cfset myArray[currentrow].name = name />
</cfloop>

<cfset arrayIndex = nameValues["WhatImLookingFor"] />

假设这个值总是存在的,你可能需要在调用之前检查StructKeyExists(nameValues, "WhatImLookingFor")。


9
在CF 10或Railo 4中,您可以使用以下代码实现:
arrayIndex = ArrayFind(arrayOfStructs, function(struct){ 
   return struct.name == "WhatImLookingFor"; 
});

它没有文档,但它有效!如果您想要所有索引,则ArrayFindAll()也是一种选择。

这个新函数类非常棒。 - rhinds
这正是我所需要的,而且在搜索多个条件时也能正常工作。我不知道是否有任何新的方法来做到这一点,但很高兴找到了这个 :) - vivasuzi

1

0

CFGroovy FTW! :)

<cfset count = 0>
<g:script>
count = myArray.find({ 
  it["NAME"] == "WhatImLookingFor" }
})
</g:script>

或者,如果你喜欢更加Java风格的(不使用闭包)

<cfset count = 0>
<g:script>
for (i in myArray) {
  if( i["NAME"] == "WhatImLookingFor" )
    count++
}
</g:script>

1
这个解决方案是否比问题中发布的原始算法更好?我对Groovy(或CFGroovy)并不很了解,但看起来你只是用另一种语言重新编写了相同的算法。就我所知,它略微更易读,可能更加优雅... 但考虑到它需要调用Groovy来运行并返回到CF,它可能几乎没有更快的机会(也许有一点点)。我猜如果在Groovy中运行非常快,那么可能值得付出额外的开销,但我还是怀疑。 - Adam Tuttle


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接