In coffescript I have
arr = ["a","b","c"]
for i in [0..arr.length] by 1
if (sometimesTrue)
arr.pop()
i--
But it is translating it to this:
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--;
}
}
You can see that this loop uses a _i
as the reference rather than i
so my i--
doesn't really do anything.
Since in this loop, the length of the array changes, I sort of need to figure out how to handle this... Is there any way to do this with a for loop? Or do I need to switch to a while?
CoffeeScript will compute the loop bounds once and you can't reset the calculation so changing the array while you're iterating over it will just make a big mess.
For example, this:
f(i) for i in [0..a.length]
becomes this:
var i, _i, _ref;
for (i = _i = 0, _ref = a.length; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
f(i);
}
Note that the number of iterations is fixed when _ref
is computed at the beginning of the loop. Also note that i
will be assigned a new value on each iteration so any changes you make to i
inside the loop will be ignored. And, note that looping over [0..a.length]
does a.length+1
iterations, not a.length
iterations; [a..b]
produces a closed interval (i.e. contains both end points), [a...b]
gives you a half-open interval (i.e. b
is not included). Similarly, this:
f(i) for i in a
becomes this:
var i, _i, _len;
for (_i = 0, _len = a.length; _i < _len; _i++) {
i = a[_i];
f(i);
}
Again, the number of iterations is fixed and changes to i
are overwritten.
If you want to mess around the the array and the loop index inside the loop then you have to do it all by hand using a while
loop:
i = 0
while i < arr.length
if(sometimesTrue)
arr.pop()
--i
++i
or:
i = 0
while i < arr.length
if(sometimesTrue)
arr.pop()
else
++i
Modifying the array you're looping over rarely does what you want in languages with for ... in ...
constructs. What you're really looking for is a filter
. Many javascript implementations have a filter function attached to the array prototype:
arr = arr.filter((member) -> !sometimesTrue)
If you can't count on this, you can use a similar CoffeeScript construct:
arr = (member for member in arr when !sometimesTrue)
Using indices in coffeescript is quite unnatural.
I think that what you want is something like :
arr = ["a","b","c"]
arr = (i for i in arr when ! sometimeTrue )
I think that you should read the following topic "Loops and Comprehensions" at http://coffeescript.org/
Sometimes it helps to take a walk, maybe in real fresh air in the woods, maybe in front of the house with a cigarrette (though your wife might hate the smoking) ...
Somtimes it even helps to talk to the rubber duck some uber-geeks have on their monitors.
And sometimes it plain and simple helps to attack the simple things from a different angle.
arr = ["a", "b", "c"]
for i in [0..arr.length]
if (sometimesTrue)
arr.splice i, 1
else i++
EDIT:
As seen in the comments below I was missing something here.
I is indeed not ignored at all, how could I've thought that in the first place?