Coldfusion cfloop over array/list不允许引用以前的值

Coldfusion cfloop over array/list不允许引用以前的值,coldfusion,cfloop,Coldfusion,Cfloop,我经常在数组或列表上使用cfloop,因为我有涉及数组值的复杂计算。但是,似乎没有办法返回到数组/列表的特定成员。如果我使用普通循环,我可以轻松做到: <cfloop from = "1" to = "#ArrayLen(myarray)#" index = "i"> <cfset temp = "myarray[i]"> <cfif mystruct[temp] GT 5> ... do something </cfif> <cfif

我经常在数组或列表上使用cfloop,因为我有涉及数组值的复杂计算。但是,似乎没有办法返回到数组/列表的特定成员。如果我使用普通循环,我可以轻松做到:

<cfloop from = "1" to = "#ArrayLen(myarray)#" index = "i">
<cfset temp = "myarray[i]">
<cfif mystruct[temp] GT 5>
  ... do something
</cfif>
<cfif myarray[i] NEQ myarray[i-1]>
  ...do something
</cfif>
</cfloop>

... 做点什么
…做点什么
但是涉及myarray[i]的计算可能会很麻烦,因为我必须用“i”而不是i处的值来引用它们

但是如果我在数组上使用循环,我通常需要添加一个计数器:

<cfset m = 0>
<cfloop array = #myarray# index = "value">
<cfset m = m + 1>
<cfif mystruct[value] GT 5>
 ... do something
</cfif> 
<cfif myarray[i] NEQ myarray[i-1]>
  ...do something
</cfif>
</cfloop>

... 做点什么
…做点什么

有人知道如何在cfloop array=myarray编码中引用myarray[i-1]吗?在研究这一点时,我发现了这样一句话:,但它没有提供任何解决方案。

开始时只是一句评论,但很快就变得太长了。我通常使用你提到的计数器。我不认为ColdFusion有一个内置的方法来为您处理这个问题。如果您只担心将当前值与以前的值进行比较,我以前做过类似的工作:

<cfset previousValue = "">
<cfloop array = #myarray# index = "value">
    <cfif mystruct[value] GT 5>
        <!--- do something --->
    </cfif> 
    <cfif value NEQ previousValue>
        <!--- do something --->
    </cfif>
    <cfset previousValue = value>
</cfloop>

您发现了ColdFusion实现数组循环的不足之处:数组中的索引/位置根本不可用

我已经知道了,还有函数中类似的失败

有一些关于这个概念的“有趣”阅读,其中讨论了各种观点(以及其中的差异)

顺便说一句,正如我在上一篇文章中所写,Railo做得很好

底线是您需要维护自己的计数器,正如您所提到的,@Miguel-F证实了这一点


投票给虫子。。。也许Adobe会在ColdFusion 11中修复它们…

让我尝试修复您的第二个示例,使其更具可读性

<cfloop from="1" to="#ArrayLen(myarray)#" index="i">
  <cfset value = myarray[i]>
  <cfif mystruct[value] GT 5>
    ... do something
  </cfif>
  <cfset lastIndex = i - 1>
  <cfif lastIndex AND value NEQ myarray[lastIndex]>
    ... do something
  </cfif>
</cfloop>

... 做点什么
... 做点什么

让我们换一种方式思考这个问题。 如果我们为了说明的目的在cfscript中重写这些内容:

  myArray=[ 'xyz', 'yyy', '232', 'uoiu', 'youneedthis', '2343'];
    writedump(myArray);
    myLongStringThing = '';

    // LOOP OVER AN INDEX AND MANUALLY PUSH YOUR ARRAY ALONG
    for ( i = 1; i <= myArray.size(); i++) {
      v = myArray[i];
      if(i < 5 && i > 1 && myArray[i] != myArray[i-1]   ){
        x = doSomethingComplicated(v);
        myArray[i] = x; // Your new computed value
      }

      if(i > 1 && v != myArray[i-1] ) {
        y = somethingElseCool(v);
        myLongStringThing &= y;
      }
    }

    writedump(myArray);
    writeoutput(myLongStringThing & '<br>');

    // LOOP THE VALUES IN THE STRUCT/ARRAY 
    i = 0;
    for (k in myArray) {
      i++;
      writeoutput('k:' & k & '<br>');
      writeoutput('a[i]:' & myArray[i] & '<br>');
    }

    function doSomethingComplicated(v) {
      Arguments.v &= 'you did it!';
      return Arguments.v;
}

    function somethingElseCool(v) {
      Arguments.v &= ';';
      return Arguments.v;
    }

    // LOOPING A STRUCT IS DIFFERENT
    myStruct = {'asdf' = 234234, 'sdfsd' = 9798, 'oiujlkj3' = 'kohjkjh'};
    for (k in myStruct) {
      writeoutput('kinstruct:' & k & '<br>');
      writeoutput('kinstruct:' & myStruct[k] & '<br>');
    }
您可以使用其中的一些,但据我所知,它们都不会返回可用的游标或索引。不过有一些可能很方便,比如subList()和equals()

最后,如果您希望在不保留手动索引的情况下查找索引,可以执行以下操作:

index = arrayFind(myArray, v)

当然,这只是按值查找索引,假设值是唯一的。使用使用索引的其中一种循环方法似乎比试图找出事件发生后的位置更安全。

如果您使用的是CF 10或Railo 4,则可以使用从到循环的索引:

_ = new Underscore();

_.each(myArray, function (value, index) {
   // loop code here
});
我建议使用一个更具表现力的函数,比如,或者,但是,这取决于您试图通过循环实现什么


注意:我写了下划线.cfc

使用您自己的计数器,就像您的第二个示例一样,但将
m
更改为
I
。请注意,
i-1
可能会产生
0
(CF索引是基于1的,0是越界的),因此请测试边缘情况。我通常只在需要像您建议的那样围绕当前索引跳转时使用您的第一个解决方案,并对基本循环使用
cfloop array=”“
。是否有任何理由试图避免索引循环?很抱歉m-i断开连接,如果
myArray
是2D或更高,并且在数组上循环,而不是引用元素的计数器
#idxTempArray[2]#…请在第五个元素之后执行操作…
。(注意,
cnt++
仅适用于CF11和更高版本,都是比较然后递增,但它保存了一行只用于递增的代码。在CF11之前,
)+1,因为这是对抗边缘情况的一个很好的步骤。我只需要担心“”这一点。看起来他们终于在2016年实现了它:我想我应该将var命名为
prevIndex
,而不是
lastIndex
,以免一时混淆它是数组的最后一个元素。如果你不想设置一个只使用一次的变量<代码>非常好的重写,i-1是一个布尔值。
_ = new Underscore();

_.each(myArray, function (value, index) {
   // loop code here
});