Last Updated: September 09, 2019
·
5.063K
· benhowdle89

Neat way to loop through an array in JS

var a = ['first', 'second', 'third'];
while(i = a.shift()){
    alert(i);
}

Nothing special, just a neat way to loop through an array in JS.

EDIT: thanks to Phuu for pointing out that I should have said this also removes the elements from the array and only if the array contains "truthys".

So be warned!

25 Responses
Add your response

I think it's important to note that this also removes the elements from the array.

over 1 year ago ·

You can also do this to iterate over "falsey" values: while ((i = a.shift()) !== undefined)

or:
while (a.length > 0) {
console.log(a.shift());
}

over 1 year ago ·

bad practice, imho. Modifying the array will eventually come back to bite you if you make it a common practice.

over 1 year ago ·

I agree, I think this would work well if you wanted to rebuild an array and remove elements (pushing the element to it after you have validated it belongs there). People using that without understanding what they are doing will lead to a bug and a head against the wall.

over 1 year ago ·

I totally agree with @johnturknett

over 1 year ago ·

I like this way if I'm sure that my array doesn't have falsy values.

var a = [1, 2, 3, 4];

for (var i=0, item; item = a[i]; i++) {
console.log('index', i, 'item', item);
}

over 1 year ago ·

how about map?

[1,null,undefined,false].map(function(x){ return x })
over 1 year ago ·

How about coffeescript list comprehension?


arr = ['first', 'second', 'third']
console.log item for item in arr
</pre>

over 1 year ago ·

Interesting approach and I could see using it. But I prefer to mutate my values as little as possible. As long as the array had not use outside of this iteration it would be fine.

over 1 year ago ·

@gxorgxo much nicer way IMHO - doesn't mess with the source array - useful for working over nodeLists too (since they won't evaluate false).

over 1 year ago ·

Beware the runtime complexity - a.shift() is much more expensive than a.pop() (O(N) vs. O(1) amortized). In practical terms, on a 100k element array you'll have a pause that feels like 10 seconds.

over 1 year ago ·

This is terrible.
You can just use .forEach
Yes, it's not guaranteed to be on all running environments (browsers), but you can easily install a fallback (https://github.com/kriskowal/es5-shim) or use jQuery's $.each

over 1 year ago ·

Take note that .forEach and $.each are usually slower than a for loop. If performance is your thing, go for @gxorgxo solution.

http://jsperf.com/for-vs-foreach/37

over 1 year ago ·

As noted previously, modifying the array you're working with, could raise issues.
For while loops, I prefer:

var arr = ['first', 'second', 'third'].reverse();
var index = arr.length;

while ( index-- ) {
  console.log( arr[index] );
}
over 1 year ago ·

I tend to just use;

var arr = ['a', 'b', 'c', 1, 2, 3, true, false, null, undefined];

for ( var n in arr ) {
      console.log( arr[n] );
}

I did a little benchmark against the solution by @silverstrike and the for in method came out faster each time.

over 1 year ago ·

@dayjo

  • I do prefer your implementation, and it used to be my preferred method for iterating through an array prior to forEach, map, and other ES5 methods.
  • My comment was in regards to the use of while loop, that in most (if not all) benchmarks that I've seen is slower then the for or for...in alternatives. "My method" just removes the problems with the method presented in the post.
  • In your example, you are missing a condition to filter out extensions to Array.prototype which is considered best practice.

On a side note: you are using var inside the for...in declaration which might bring the wrath of Douglas Crockford upon you ;)

over 1 year ago ·

This looping method can't be use if we need to retain the values in the array.

over 1 year ago ·

@silverstrike, indeed! I shall watch my vars from now on :P

over 1 year ago ·

How about a sexy CoffeeScript + functional programming combo instead? :)

arr = [a, b, c, ...]

arr.each (i)-> alert i

_.each arr, (i)-> alert i
over 1 year ago ·

absolutely, @ssoroka
I'd stay away of these kind of practices unless it is exactly what I'm trying to do.
Want cool looping? Then use ruby. :inserttrollface_here:

over 1 year ago ·

why not forEach?

over 1 year ago ·

This works all the time:

JS Array

var someArray = ['one', 'two', 'three'];
for ( var i in someArray ) {
      console.log( someArray[i] );
}
</code></pre>

JSON Array

var someArray = [ {'id': 1, 'name': 'foo'}, {'id': 2, 'name': 'bar'} ];
for ( var i in someArray ) {
      console.log( someArray[i].id );
      console.log( someArray[i].name );
}
</code></pre>
over 1 year ago ·

Why?

It might be a nice trick, but that's all it is.

over 1 year ago ·

forEach is your friend also Array in javascript.

over 1 year ago ·
over 1 year ago ·