"foreach" in JavaScript

As an example, in PHP we have the function foreach() ( that allows us to execute certain code for each element found in an array:

<?php
$arr = array(1, 2, 3, 4, 5, 6);

foreach ($arr as $value) {
  echo "acção para o valor " . $value;
}

// Saída:
// acção para o valor 1
// ...
?>

Using the same function, we can go through the array and get the key and its value for each element found:

<?php
$arr = array(
  "primeiro" => "John",
  "ultimo"   => "Doe"
);

foreach ($arr as $key => $value) {
  echo $key . ' nome: ' . $value . "<br>";
}

// Saída:
// primeiro nome: John
// ultimo nome: Doe
?>

Question

How can I perform this type of operations with an array in JavaScript ?

Author: Zuul, 2014-01-28

6 answers

First of all, PHP arrays are different from JavaScript arrays

An example of a traditional matrix would be:

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

What in PHP is an associative array, in JavaScript is an object:

var obj = {
    primeiro: 'John',
    ultimo: 'Doe'
};

As @utluiz said, in JavaScript there is for..in , which serves to iterate over the keys of an object. Since arrays are also objects, it is also possible to iterate over them, but this is not recommended due to some features do for..in:

  1. the for..in iterates over all enumerable keys of the object.
  2. the for..in also iterates over all (enumerable) property keys inherited from the object prototype.
  3. the JavaScript specification does not require a specific order for the keys traversed by for..in. Different browsers can use different orders and it is possible that vector keys are not accessed in ascending order.

These characteristics can bring problems, especially if you use libraries or polyfills that modify Array.prototype.

So don't use for..in to iterate over an array; use a common for

var matriz = [1,2,3,4];
for(var i=0; i<matriz.length; i++) {
    console.log(i, matriz[i]); // i é o índice, matriz[i] é o valor
}

If you want something a little closer to the PHP version:

var matriz = [1,2,3,4];
for(var chave=0, valor; valor=matriz[chave], chave<matriz.length; chave++) {
    console.log(chave, valor); // chave é o índice, valor é o valor
}

There are still other alternatives, in browsers with ECMAScript 5 support (which does not include IE8). For example, the forEach mentioned by Luiz Vieira:

var matriz = [1,2,3,4];
matriz.forEach(function(valor, chave){
    console.log(chave, valor);
});

If the goal of the iteration is create a new array with transformations of the orignal values, you can use the map:

var matriz = [1,2,3,4];
// Nova matriz onde cada valor é o dobro
var dobros = matriz.map(function(valor){
    return valor * 2;
});
console.log(dobros); // [2,4,6,8];

If the goal is to create a new array with only some of the orignal values, you can use the filter:

var matriz = [1,2,3,4];
// Nova matriz só com valores pares
var pares = matriz.filter(function(valor){
    return valor % 2 == 0;
});
console.log(pares); // [2,4];

In this same line, it is worth taking a look at the methods reduce, every e some.

To iterate over objects, then use for..in

var obj = {
    primeiro: 'John',
    ultimo: 'Doe'
};
for(var tipoNome in obj) {
    console.log(tipoNome, obj[tipoNome]);
}

But beware: this type of iteration may include inherited properties. For example:

function Cachorro(nome) {
    this.nome = nome;
}
Cachorro.prototype.latir = function() {
    console.log('au au!');    
};
var godofredo = new Cachorro('Godofredo');
for(var prop in godofredo) {
    console.log(prop); // loga 'latir' e 'nome'
}

To avoid the problem, you can check with hasOwnProperty:

for(var prop in godofredo) {
    if(godofredo.hasOwnProperty(prop)) {
        console.log(prop); // loga somente 'nome'
    }
}    
 30
Author: bfavaretto, 2020-06-11 14:45:34

Via jQuery, by a simple approach, you can use the jQuery method.each () which allows iterating over objects / arrays by separating them by index / value

Example:

$.each([ 'a', 'b', 'c' ], function( index, value ) {
    alert( index + ": " + value );
});

Reference: http://api.jquery.com/jquery.each /

 8
Author: Daniel, 2014-01-29 04:15:17

Similar alternative: for..in

In Javascript there is a version of for that has some similarities to PHP's foreach. It is the closest construction type, but it exists to iterate over object properties and not necessarily vector indexes. Also, it is not possible to get the key and value automatically.

The syntax is:

for (<índice> in <vetor/objeto>)

Example:

var array = [1, 2, 3, 4];
for (index in array) {
    var value = array[index];
    console.log("array[" + index + "] = " + value);
}

Functional example in jsfiddle .

Iterating about properties of objects

As I mentioned, this type of loop is not directed exactly to arrays , being useful mainly for iterating over the properties of any object:

Example:

var object = { nome: 'Luiz', idade: 29};
for (property in object) {
    var value = object[property];
    console.log("object[" + property + "] = " + value);
}

Functional example in jsfiddle .

A common application is to simulate a map or data dictionary. Another example is a sparse vector (which does not contain all indexes sequentially from 0 to n.

Attention for possible problems

As mentioned in other answers and comments, looping for...in can result in unwanted side effects.

For example, if a library defines one or more functions in the object's prototype. These functions will be included in the for..in Loop and you would need to use the hasOwnProperty function to ignore these "inherited"functions.

Also, it is not guaranteed that numeric indexes will be traversed in any order.

Tip: Avoid fiddling in prototype

From my point of view, tampering with the prototype of common objects should be avoided at all costs, as should libraries that make such use.

For example, imagine that we are going to use an object as a map, dynamically assigning and retrieving attributes from it. When scrolling through the keys of this map, I will have to remember to always use the function .

The question is, Should we really have to worry if has anyone injected some "strange" element into our objects? I believe not.

In practice...

While for..in is always accused of causing problems, in my experience I have never had difficulty using it on both arrays and normal objects, withouthasOwnProperty. This is probably due to the fact that I never allow "strange" code by injecting "magic" functions without my knowledge.

Also, although the order of the elements is not guaranteed by the specification, I have also never witnessed in any browser indexes being traversed out of order, at least in arrays for real.

See the example below:

var array = new Array();

array.push("A");
array.push("B");
array.push("C");

delete array[1]
array[1] = 2;

for (i in array) {
    console.log(i)
}

Even deleting a middle index from the array and then resetting it, the result will be 0, 1 and 2, in this order. See the jsfiddle . If anyone discovers any browser that behaves differently, please let me know.

On the other hand, if do not use a true array the result is different. See the example below:

var array = { }

array[0] = "A";
array[2] = "B";
array[1] = "C";

for (i in array) {
    console.log(i)
}

See the jsfiddle.

Surprisingly, the result in Chrome is 0, 1 and 2. However, in Firefox and IE it is 0, 2 and 1. Anyway, unless you use an object as a sparse vector, i.e. adding larger elements before smaller ones, there would be no problem using for..in.

Anyway, the same care for use of for..in in arrays fits any object, so recommendations like "Don't use this" just don't make sense. Even if the prototype is changed, as long as I always use the hasOwnProperty() and don't care about the order of the elements, there are no problems using this type of loop.

Final considerations

In general, it is really better to avoid the for..in and opt for the traditional for. Reasons:

  • you may need a library that changes prototype. It is common to hear reports of people adding a certain Javascript library and it "breaks" its implementation.
  • also prevents other developers from misusing prototype and breaking the overall system code.
  • Allows objects to simulate a array by setting the length property and numeric attributes. This is very useful for generic routines that receive vectors. See the example below:

    var array = {
        0: "Primeiro",
        1: "Segundo",
        2: "Terceiro",
        length: 3
    };
    
    for (var i = 0; i < array.length; i++) {
        console.log('array[' + i + '] = ' + array[i]);
    }
    

See the jsfiddle .

 8
Author: utluiz, 2018-07-30 03:17:21

In addition to all existing answers, there is for...of from ECMAScript 6 (i.e. new :/) which traverses values of objects including a special property Symbol.iterator (this property is a symbol... and remembering that symbols are not enumerable!). Instances of Array, Map, Set, String and TypedArray, and the object arguments generated by functions are already walkable, as long as they have the special property Symbol.iterator.

Note: there is only one downside to using for... of . It does not let you know what the index of the current value.

P.S.: the classes / interfaces cited above store this property Symbol.iterator in prototype itself. This property should return a function (if you see in the console, [][Symbol.iterator], you will come across a function named 'values'), and that same function should return an object. [][Symbol.iterator]() returns a native instance of ArrayIterator.

Example of traversing a Array with key pairs and value:

const pairs = [
    [ 'yum', 'yam' ],
    [ 'haha', true ]
];

for (let [k, v] of pairs) {
    console.log(k, v);
}

Example traversing a Array in a common way:

for (let v of [ 1, 2, 3 ]) {
    console.log(v);
}
 4
Author: Klaider, 2017-01-13 22:42:35

This example (extracted from this original source in OS (en) ) uses the function forEach existing in objects of type array from ECMAScript5:

var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});
 1
Author: Luiz Vieira, 2017-05-23 12:37:27

var i = -1; while(vetor[++i]){}

I tested on Chrome and it works fine !

 -2
Author: Arquimedes de Siracusa, 2016-09-12 18:02:29