0

在咖啡里我有

arr = ["a","b","c"]
for i in [0..arr.length] by 1
  if (sometimesTrue)
    arr.pop()
    i--

但它正在将其翻译为:

var arr, i, _i, _ref;

arr = ["a", "b", "c"];

for (i = _i = 0, _ref = arr.length; _i <= _ref; i = _i += 1) {
  if (sometimesTrue) {
    arr.pop();
    i--;
  }
}

你可以看到这个循环使用 a_i作为参考,而不是imyi--并没有真正做任何事情。

由于在这个循环中,数组的长度发生了变化,我有点需要弄清楚如何处理这个......有没有办法用 for 循环来做到这一点?还是我需要切换到一段时间?

4

4 回答 4

2

CoffeeScript 将计算一次循环边界,并且您无法重置计算,因此在迭代时更改数组只会造成很大的混乱。

例如,这个:

f(i) for i in [0..a.length]

变成这样:

var i, _i, _ref;
for (i = _i = 0, _ref = a.length; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
  f(i);
}

请注意,在_ref循环开始时计算的迭代次数是固定的。另请注意,i每次迭代都会为它分配一个新值,因此您i在循环内所做的任何更改都将被忽略。并且,请注意,循环[0..a.length]a.length+1迭代,而不是a.length迭代;[a..b]产生一个闭区间(即包含两个端点),[a...b]给你一个半开区间(即b不包括在内)。同样,这个:

f(i) for i in a

变成这样:

var i, _i, _len;
for (_i = 0, _len = a.length; _i < _len; _i++) {
  i = a[_i];
  f(i);
}

同样,迭代次数是固定的,并且更改会i被覆盖。

如果您想弄乱循环内的数组和循环索引,那么您必须使用while循环手动完成所有操作:

i = 0
while i < arr.length
  if(sometimesTrue)
    arr.pop()
    --i
  ++i

或者:

i = 0
while i < arr.length
  if(sometimesTrue)
    arr.pop()
  else
    ++i
于 2012-11-15T04:29:11.787 回答
1

for ... in ...修改您正在循环的数组很少能在具有构造的语言中实现您想要的效果。你真正要找的是一个filter. 许多 javascript 实现都有一个过滤器函数附加到数组原型:

arr = arr.filter((member) -> !sometimesTrue)

如果你不能指望这一点,你可以使用类似的 CoffeeScript 构造:

arr = (member for member in arr when !sometimesTrue)
于 2012-11-17T17:47:52.637 回答
-1

在 coffeescript 中使用索引是很不自然的。

我认为你想要的是这样的:

arr = ["a","b","c"]
arr = (i for i in arr when ! sometimeTrue )

我认为您应该在http://coffeescript.org/阅读以下主题“循环和理解”

于 2012-11-15T07:44:49.687 回答
-2

有时散步会有所帮助,也许在树林里真正新鲜的空气中,也许在屋前抽着香烟(尽管你的妻子可能讨厌吸烟)......有时甚至可以和橡皮鸭交谈一些超级-geeks 在他们的显示器上。有时,简单明了有助于从不同的角度攻击简单的事情。 arr = [“a”,“b”,“c”]

for i in [0..arr.length]
  if (sometimesTrue)
    arr.splice i, 1
  else i++

编辑:正如下面的评论中所见,我在这里遗漏了一些东西。我确实没有被忽视,我一开始怎么会这么想?

于 2012-11-15T02:02:09.350 回答