根据您在上面提供的要点 (https://cffiddle.org/app/file?filepath=3e26c1ac-d5db-482f-9bb2-995e6cabe704/49b3e106-8db9-4411-a6d4-10deb3f8cb0e/24e44eba-45ef-4744-a6e6-53395c09a344.cfm),我认为您已经稍微澄清了您的期望。
在您的要点中,您说您希望能够搜索结构数组并找到具有"name" 键且值为"form" 的行。然后,您想要获取与数组行中的该结构关联的 "value" 键的值。如果没有value,则返回0。
您希望能够在一行代码中做到这一点,而上述答案确实做到了。我的回答基本上建立在这些之上。
如前面的答案所示,您仍然希望使用闭包函数来过滤最终输出。这些速度非常快,基本上是为了做你想做的事情。
我使用的 Fiddle 在这里:https://cffiddle.org/app/file?filepath=b3507f1d-6ac2-4900-baed-fb3faf5a3b3a/e526afc2-bb85-4aea-ad0e-dcf38f52b642/75d88d2b-f990-44c1-9d9f-22931bf9d4d7.cfm
我已经用这个做了两件事。
首先,我的工作就像您希望为您的过滤值遇到多个记录一样,然后将它们转换为逗号分隔的列表。如果您需要其他结构,可以修改我代码中的reduce() 函数来处理。
其次,我的工作就像您希望只遇到一个过滤记录一样,只返回一个值。
我做的第一件事,这两种方法基本相同,与前面的答案基本相同,就是过滤原始数组以获得所需的值。
这样做是这样的:
myResult = originalArray.filter(
function(itm){
return itm?.name=="form"; /// ?. = safe-navigation operator.
}
)
为了清楚起见,我将它分成多行。
这将返回一个由过滤后的行组成的新结构数组。
但是您想获取这些记录并从这些行中返回 "value"(如果没有值,则默认为 0。您可以使用 reduce() 执行此操作。
commaDelimitedValue =
myResult.reduce(
function(prev,nxt) {
return prev.listappend( ( nxt.value.len() ? nxt.value : 0 ) ) ;
}
, "" /// Initialization value
) ;
同样,这可以写在一行中,但为了清楚起见,我包含了换行符。
reduce() 函数本质上只是将您的输入减少为单个值。它遵循.reduce( function( previousValue, nextValue ){ return .... },<initializationValue>) 的格式,其中,在第一次迭代中,initializationValue 被替换为previousValue,然后previousValue 成为该迭代的结果。 nextValue 实际上是您将从中得出结果的当前迭代。
更多信息:https://coldfusion.adobe.com/2017/10/map-reduce-and-filter-functions-in-coldfusion/
在我的假设中,您可能会从您的filter() 返回多行。您获取这些行并将value 附加到逗号分隔的列表中。因此,您最终会得到类似 20,10,0,0 的结果 - 代表过滤结果中的 4 行。
我还检查value 的长度,如果它是空字符串,则默认为0。上面,我说过你可以只使用 Elvis 运算符 (:?),但这不适用于像空字符串这样的简单值。 Elvis 与 NULLs 一起使用,早期的数组确实有。
要回到一行,您可以链接这两个函数。所以你最终得到:
myFinalResult =
myOriginalArray.filter(
function(itm){
return itm?.name=="form";
}
)
.reduce(
function(prev,nxt) {
return prev.listappend( ( nxt.value.trim().len() ? nxt.value : 0 ) ) ;
}
, ""
)
;
同样,该代码做了很多工作,但它本质上仍然是一行。最终结果将再次类似于 "20,10,0,0" 4 行,其中 2 默认为 0。
如果您只希望您的过滤器返回一行,或者您只需要一个值,您可以稍微简化一下。
myFinalResult = myOriginalArray.filter( function(itm){ return itm?.name=="fm" && (itm?.value.trim().len()>0) ; } )[1]["value"] ?: 0 ;
有了这个,我又回到了使用我之前的猫王技巧来默认没有value的行,因为我正在过滤掉带有空字符串"value"的"form"结构。 && 与 AND 相同。从技术上讲,这个 CAN 从原始数组中过滤了不止一行,但[1] 只会从过滤后的行中选择第一行。它也不需要使用reduce()。如果过滤的行不止一行,则每次迭代都会覆盖前一个。
这将返回一个简单的单一值,类似于 42 - 这是数组中最后过滤的值,因为它会覆盖前一行的值。
我的 Fiddle (https://cffiddle.org/app/file?filepath=b3507f1d-6ac2-4900-baed-fb3faf5a3b3a/e526afc2-bb85-4aea-ad0e-dcf38f52b642/75d88d2b-f990-44c1-9d9f-22931bf9d4d7.cfm) 有一些额外的 cmets,我设置了几个边缘案例来演示过滤和安全导航。
我还想重申,如果这是 Lucee 5+ 或 ACF2018+,您可以使用箭头函数进一步缩短它。