This has nothing to do with the target you’re compiling to, or incorrect types. The problem is that you’re iterating forwards when you should be iterating backwards.
Let’s consider a simpler example:
var array:Array<String> = ["a", "b", "c", "d"];
for(i in 0...array.length) {
if(i == 1) {
array.splice(i, 1);
} else {
trace(array[i]);
}
}
This code is meant to print “acd
.” However, instead of doing that, it prints “ad
” and then crashes. Can you see why?
Consider each iteration of the loop:
-
i == 0
, so the code prints “a
.”
-
i == 1
, so the code removes index 1 from the array and doesn’t print anything. The array is now ["a", "c", "d"]
.
-
i == 2
, so the code prints “d
.”
-
i == 4
, so the code crashes when it tries to read from the array.
See the problem? After splice()
was called, the array got shorter, but the iterator wasn’t updated to reflect this. To make this algorithm work, you’d have to subtract 1 from both i
and the iterator’s end value, but neither of those is allowed on an IntIterator
instance.
Assuming you don’t care about order, here’s an easier solution.
var array:Array<String> = ["a", "b", "c", "d"];
var i:Int = array.length;
while(i-- > 0) { //Just for fun, you could type it as "i --> 0".
if(i == 1) {
array.splice(i, 1);
} else {
trace(array[i]);
}
}
Output is dca
, with no crash. The splice()
call affects things at or above index i
, but after that, the loop only looks at things below index i
.
By the way, there’s a second bug in there that can be fixed by a continue statement. Can you figure out where?