While Loop with Array.pop() Gotcha
Copy link to clipboard
Copied
Just a bit of a heads up:
A number of us have been using a while(obj=array.pop()){} construct for a while. (I believe Marc was the one to introduce this construct to this forum.)
While this is considerably more efficient than a standard for loop when you don't need the array when the loop ois done, there's a not-so-obvious gotcha:
0 in javascript is evaluated to false, so : while(0) is equivalent to while(false).
If you have an loop like this:
ar = [1,0,8,6];
while(a=ar.pop()){
// do your stuff
}
6 and 8 will resolve true, but 0 will not. The loop will exit when it hits 0, and neither 0 nor 1 will be processed.
This loop is no good either:
ar = [1,0,8,6];
while(a=ar.pop() != null){
//do your stuff
}
because "a" will evaluate to either true or false instead of the value of the array because statements are processed backwards (i.e. a = (ar.pop != null)).
Instead you need (note the extra parenthesis):
ar = [1,0,8,6];
while((a=ar.pop()) != null){
//do your stuff
}
HTH,
Harbs
Copy link to clipboard
Copied
Actually, even the last construct is not safe. If there's a null object in the array it'll exit prematurely as well.
For null objects, this will work:
ar = [1,null,8,6];
while((a=ar.pop()) !== undefined){
//do your stuff
}
But if you have a non-consecutive array this too will fall flat on its face:
ar = [1,null,8,6];
ar[6] = 2;
while((a=ar.pop()) !== undefined){
//this will only process 2
}
Bottom line, don't use the pop() as the condition of the loop. Do something like this instead:
ar = [1,null,8,6];
ar[6] = 2;
while(ar.length){
a=ar.pop();
// now we can process all elements of the array!
}
Harbs
Copy link to clipboard
Copied
Good point, Harbs 😉
That's why I wouldn't recommand using the while( a=ar.pop() ){...} pattern on simple one-dimensional arrays that contain, or could contain primitive types. As a general rule I use this tip on temporary arrays of objects, or on n-dimensional temporary arrays, because I am absolutely sure that none of the elements can be evaluated to false. Then it is a useful shortcut. In other situations the old good index loop is the best although it requires an additional variable.
@+
Marc
Copy link to clipboard
Copied
Hi Marc,
I wasn't blaming you for my mistakes! I just got bitten by using this technique for primitive type arrays, and I figured I should prevent others from making my mistake...
But even for primitive arrays, while(array.length)array.pop() is more efficient than a for loop.
Harbs

