Como posso percorrer todas as entradas em uma matriz usando JavaScript?
Eu pensei que era algo assim:
forEach(instance in theArray)
Onde theArray
é minha matriz, mas isso parece estar incorreto.
Edit: Esta resposta está desesperadamente desatualizada. Para uma abordagem mais moderna, veja os métodos disponíveis em uma matriz . Os métodos de interesse podem ser:
A maneira padrão de iterar uma matriz em JavaScript é um loop for
-baunilha:
var length = arr.length,
element = null;
for (var i = 0; i < length; i++) {
element = arr[i];
// Do something with element
}
Observe, no entanto, que essa abordagem só é boa se você tiver uma matriz densa e cada índice estiver ocupado por um elemento. Se o array é escasso, então você pode ter problemas de performance com esta abordagem, já que você irá iterar em cima de muitos índices que não realmente existem no array. Nesse caso, um loop for .. in
pode ser uma ideia melhor. No entanto, você deve usar as proteções apropriadas para garantir que apenas as propriedades desejadas da matriz (isto é, os elementos da matriz) sejam acionadas, já que o loop for..in
também será enumerado em navegadores herdados ou se as propriedades adicionais forem definidas como enumerable
.
Em ECMAScript 5 haverá um método forEach no protótipo de matriz, mas não é suportado em navegadores herdados. Portanto, para poder usá-lo consistentemente, você deve ter um ambiente que ofereça suporte a ele (por exemplo, Node.js para JavaScript do lado do servidor) ou use um "Polyfill". O Polyfill para essa funcionalidade é, no entanto, trivial e, como facilita a leitura do código, é um bom polyfill para incluir.
Se você estiver usando a biblioteca jQuery , você pode usar jQuery.each :
$.each(yourArray, function(index, value) {
// do your stuff here
});
EDIT:
Como por questão, o usuário quer código em javascript em vez de jquery, então a edição é
var length = yourArray.length;
for (var i = 0; i < length; i++) {
// Do something with yourArray[i].
}
Algumas linguagens de estilo C - usam foreach
para percorrer as enumerações. Em JavaScript isso é feito com a estrutura de loop for..in
:
var index,
value;
for (index in obj) {
value = obj[index];
}
Existe uma pegadinha. for..in
fará um loop através de cada um dos membros enumeráveis do objeto, e os membros em seu protótipo. Para evitar a leitura de valores que são herdados através do protótipo do objeto, simplesmente verifique se a propriedade pertence ao objeto:
for (i in obj) {
if (obj.hasOwnProperty(i)) {
//do stuff
}
}
Além disso, ECMAScript 5 adicionou um método forEach
a Array.prototype
, que pode ser usado para enumerar um array usando um retorno (o polyfill está nos documentos, então você ainda pode usá-lo para navegadores mais antigos):
arr.forEach(function (val, index, theArray) {
//do stuff
});
É importante observar que Array.prototype.forEach
não quebra quando o retorno de chamada retorna false
. jQuery e Underscore.js fornecem suas próprias variações em each
para fornecer loops que podem ser curto-circuitados.
Se você quiser fazer um loop em uma matriz, use o loop for
padrão de três partes.
for (var i = 0; i < myArray.length; i++) {
var arrayItem = myArray[i];
}
Você pode obter algumas otimizações de desempenho armazenando em cache myArray.length
ou iterando-o de trás para frente.
Se você não se importa de esvaziar a matriz:
var x;
while(x = y.pop()){
alert(x); //do something
}
x
conterá o último valor de y
e será removido do array. Você também pode usar shift()
, que dará e removerá o primeiro item de y
.
Uma implementação de forEach ( veja em jsFiddle ):
function forEach(list,callback) {
var length = list.length;
for (var n = 0; n < length; n++) {
callback.call(list[n]);
}
}
var myArray = ['hello','world'];
forEach(
myArray,
function(){
alert(this); // do something
}
);
Uma solução fácil agora seria usar a biblioteca underscore.js . Ele está fornecendo muitas ferramentas úteis, como each
e delegará automaticamente o trabalho para o forEach
nativo, se disponível.
Um exemplo CodePen de como funciona é:
var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});
Array.prototype.forEach()
nativo.for each (variable in object)
está obsoleto como parte do padrão ECMA-357 ( EAX ).for (variable of object)
como a parte da proposta do Harmony (ECMAScript 6).Existem três implementações de foreach
em jQuery como segue.
var a = [3,2];
$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3
Provavelmente, o loop for(i = 0; i < array.length; i++)
não é a melhor escolha. Por quê? Se você tem isso:
var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";
O método chamará de array[0]
para array[2]
. Primeiro, isso fará referência a variáveis que você nem tem, segundo você não teria as variáveis na matriz e, em terceiro lugar, tornará o código mais ousado. Olha aqui, é o que eu uso:
for(var i in array){
var el = array[i];
//If you want 'i' to be INT just put parseInt(i)
//Do something with el
}
E se você quiser que seja uma função, você pode fazer isso:
function foreach(array, call){
for(var i in array){
call(array[i]);
}
}
Se você quiser quebrar, um pouco mais de lógica:
function foreach(array, call){
for(var i in array){
if(call(array[i]) == false){
break;
}
}
}
Exemplo:
foreach(array, function(el){
if(el != "!"){
console.log(el);
} else {
console.log(el+"!!");
}
});
Ele retorna:
//Hello
//World
//!!!
A partir do ES6:
list = [0, 1, 2, 3]
for (let obj of list) {
console.log(obj)
}
Onde of
evita as esquisitices associadas a in
e faz com que funcione como o loop for
de qualquer outra linguagem, e let
liga i
dentro do loop em oposição a dentro da função.
As chaves ({}
) podem ser omitidas quando há apenas um comando (por exemplo, no exemplo acima).
Este é um iterador para a lista NON-SPARSE, onde o índice começa em 0, que é o cenário típico quando se lida com document.getElementsByTagName ou document.querySelectorAll)
function each( fn, data ) {
if(typeof fn == 'string')
eval('fn = function(data, i){' + fn + '}');
for(var i=0, L=this.length; i < L; i++)
fn.call( this[i], data, i );
return this;
}
Array.prototype.each = each;
Exemplos de uso:
Exemplo 1
var arr = [];
[1, 2, 3].each( function(a){ a.Push( this * this}, arr);
arr = [1, 4, 9]
Exemplo # 2
each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');
Cada tag p recebe class="blue"
Exemplo # 3
each.call(document.getElementsByTagName('p'),
"if( i % 2 == 0) this.className = data;",
'red'
);
Todas as outras tags p recebem class="red"
>
Exemplo # 4
each.call(document.querySelectorAll('p.blue'),
function(newClass, i) {
if( i < 20 )
this.className = newClass;
}, 'green'
);
E finalmente as primeiras 20 tags p azuis são alteradas para verde
Cuidado ao usar string como função: a função é criada fora de contexto e deve ser usada apenas quando você tiver certeza do escopo da variável. Caso contrário, é melhor passar funções em que o escopo é mais intuitivo.
Não há nenhum loop for each
no nativo JavaScript . Você pode usar bibliotecas para obter essa funcionalidade (recomendo Underscore.js ), use um loop for
simples.
for (var instance in objects) {
...
}
No entanto, note que pode haver razões para usar um loop for
ainda mais simples (veja a questão do Stack Overflow Por que usar o “for… in” com iteração de array é uma idéia tão ruim?)
var instance;
for (var i=0; i < objects.length; i++) {
var instance = objects[i];
...
}
Existem algumas maneiras para percorrer uma matriz em JavaScript, como abaixo:
for - é o mais comum. Bloco completo de código para loop
var languages = ["Java", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>
while - loop enquanto uma condição é finalizada. Parece ser o ciclo mais rápido
var text = "";
var i = 0;
while (i < 10) {
text += i + ") something<br>";
i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>
do/while - também percorre um bloco de código enquanto a condição é verdadeira, será executada pelo menos uma vez
var text = ""
var i = 0;
do {
text += i + ") something <br>";
i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>
Loops funcionais - forEach
, map
, filter
, também reduce
(eles percorrem a função, mas são usados se você precisar fazer algo com sua matriz, etc.
// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>
Para mais informações e exemplos sobre programação funcional em arrays, veja o post do blog Programação funcional em JavaScript: map, filter e reduce.
ECMAScript5 (a versão no Javascript) para trabalhar com Arrays.
forEach - Itera cada item na matriz e faz o que você precisa com cada item.
['C', 'D', 'E'].forEach(function(element, index) {
console.log(element + " is the #" + (index+1) + " in musical scale");
});
// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale
No caso, mais interessado em operação em array usando algum recurso embutido.
map - Cria um novo array com o resultado da função callback. Esse método é bom para ser usado quando você precisa formatar os elementos da sua matriz.
// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
return elem.toUpperCase();
});
// Output: ['BOB', 'JOE', 'JEN']
reduzir - Como o nome diz reduz a matriz a um valor único, chamando a função dada passando no elemento currenct e o resultado da execução anterior.
[1,2,3,4].reduce(function(previous, current) {
return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10
every - Retorna true ou false se todos os elementos da matriz passarem no teste na função de retorno de chamada.
// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];
ages.every(function(elem) {
return elem >= 18;
});
// Output: false
filter - Muito semelhante a todos, exceto que o filtro retorna um array com os elementos que retornam true para a função dada.
// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
return (elem % 2 == 0)
});
// Output: [2,4,6]
Espero que isso seja útil.
Não há capacidade inata de quebrar forEach
. Para interromper a execução use o Array#some
como abaixo:
[1,2,3].some(function(number) {
return number === 1;
});
Isso funciona porque some
retorna true assim que qualquer um dos retornos de chamada, executados em ordem de matriz, retorna true, causando um curto-circuito na execução do resto. Resposta Original Veja Protótipo de matriz para alguns
Eu também gostaria de adicionar isso como uma composição de um loop reverso e uma resposta acima para alguém que também gostaria dessa sintaxe.
var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
console.log(item);
}
Prós:
O benefício para isso: Você já tem a referência no primeiro como esse que não precisará ser declarado posteriormente com outra linha. É útil ao fazer loop através da matriz de objetos.
Contras:
Isto irá quebrar sempre que a referência for falsa - falsey (indefinida, etc.). Pode ser usado como uma vantagem embora. No entanto, isso tornaria um pouco mais difícil de ler. E também dependendo do navegador, ele pode "não" ser otimizado para funcionar mais rápido que o original.
jQuery maneira de usar $.map
:
var data = [1, 2, 3, 4, 5, 6, 7];
var newData = $.map(data, function(element) {
if (element % 2 == 0) {
return element;
}
});
// newData = [2, 4, 6];
Um caminho mais próximo de sua idéia seria usar Array.forEach()
que aceita uma função de clojure que será executada para cada elemento da matriz.
myArray.forEach(
(item) => {
// do something
console.log(item);
}
);
Outra forma viável seria usar Array.map()
, que funciona da mesma forma, mas também mutates
cada elemento e retorna como:
var myArray = [1, 2, 3];
myArray = myArray.map(
(item) => {
return item + 1;
}
);
console.log(myArray); // [2, 3, 4]
Usando Loops com ES6 desestruturadora e operador de propagação
A desestruturação e o uso do spread operator mostraram-se bastante úteis para os recém-chegados ao ES6 como sendo mais legíveis/estéticos, embora alguns veteranos do javascript possam considerá-lo confuso, juniores ou outras pessoas podem achar útil.
Os exemplos a seguir usarão
for...of
statement e.forEach
method.Exemplos 6, 7 e 8 pode ser usado com quaisquer loops funcionais como
.map
,.filter
,.reduce
,.sort
,.every
,.some
, para obter mais informações sobre esses métodos, verifique o Array Object .
Exemplo 1: Normal for...of
loop - não há truques aqui.
let arrSimple = ['a', 'b', 'c'];
for (let letter of arrSimple) {
console.log(letter);
}
Exemplo 2: Dividir palavras para caracteres
let arrFruits = ['Apple', 'orange', 'banana'];
for (let [firstLetter, ...restOfTheWord] of arrFruits) {
// Create a shallow copy using the spread operator
let [lastLetter] = [...restOfTheWord].reverse();
console.log(firstLetter, lastLetter, restOfTheWord);
}
Exemplo 3: Looping com um key
e value
// let arrSimple = ['a', 'b', 'c'];
// Instead of keeping an index in `i` as per example `for(let i = 0 ; i<arrSimple.length;i++)`
// this example will use a multi-dimensional array of the following format type:
// `arrWithIndex: [number, string][]`
let arrWithIndex = [
[0, 'a'],
[1, 'b'],
[2, 'c'],
];
// Same thing can be achieved using `.map` method
// let arrWithIndex = arrSimple.map((i, idx) => [idx, i]);
// Same thing can be achieved using `Object.entries`
// NOTE: `Object.entries` method doesn't work on internet Explorer unless it's polyfilled
// let arrWithIndex = Object.entries(arrSimple);
for (let [key, value] of arrWithIndex) {
console.log(key, value);
}
Example 4: Obtém propriedades do objeto inline
let arrWithObjects = [{
name: 'Jon',
age: 32
},
{
name: 'Elise',
age: 33
}
];
for (let { name, age: aliasForAge } of arrWithObjects) {
console.log(name, aliasForAge);
}
Exemplo 5: Obtenha propriedades de objetos profundos do que você precisa
let arrWithObjectsWithArr = [{
name: 'Jon',
age: 32,
tags: ['driver', 'chef', 'jogger']
},
{
name: 'Elise',
age: 33,
tags: ['best chef', 'singer', 'dancer']
}
];
for (let { name, tags: [firstItemFromTags, ...restOfTags] } of arrWithObjectsWithArr) {
console.log(name, firstItemFromTags, restOfTags);
}
Exemplo 6: É Exemplo 3 usado com .forEach
let arrWithIndex = [
[0, 'a'],
[1, 'b'],
[2, 'c'],
];
// Not to be confused here, `forEachIndex` is the real index
// `mappedIndex` was created by "another user", so you can't really trust it
arrWithIndex.forEach(([mappedIndex, item], forEachIndex) => {
console.log(forEachIndex, mappedIndex, item);
});
Exemplo 7: É Exemplo 4 usado com .forEach
let arrWithObjects = [{
name: 'Jon',
age: 32
},
{
name: 'Elise',
age: 33
}
];
// NOTE: Destructuring objects while using shorthand functions
// are required to be surrounded by parenthesis
arrWithObjects.forEach( ({ name, age: aliasForAge }) => {
console.log(name, aliasForAge)
});
Exemplo 8: É Exemplo 5 usado com .forEach
let arrWithObjectsWithArr = [{
name: 'Jon',
age: 32,
tags: ['driver', 'chef', 'jogger']
},
{
name: 'Elise',
age: 33,
tags: ['best chef', 'singer', 'dancer']
}
];
arrWithObjectsWithArr.forEach(({
name,
tags: [firstItemFromTags, ...restOfTags]
}) => {
console.log(name, firstItemFromTags, restOfTags);
});
A sintaxe lambda normalmente não funciona em IE 10 ou abaixo.
Eu costumo usar o
[].forEach.call(arrayName,function(value,index){
console.log("value of the looped element" + value);
console.log("index of the looped element" + index);
});
If you are a jQuery Fan and already have a jQuery file running, you should reverse the positions of the index and value parameters
$("#ul>li").each(function(**index,value**){
console.log("value of the looped element" + value);
console.log("index of the looped element" + index);
});
Você pode ligar paraEn assim:
let Array = [1,3,2];
theArray.forEach((element)=>{
// use the element of the array
console.log(element)
}
elemento terá o valor de cada índice de 0 para o comprimento da matriz.
Saída:
1
3
2
Explicação
forEach está na classe de protótipo. você também pode chamar isso de theArray.prototype.forEach (...);
protótipo: https://hackernoon.com/prototypes-in-javascript-5bba2990e04b
Você também pode alterar um array como este:
for(let i=0;i<theArray.length;i++){
console.log(i); //i will have the value of each index
}
se você quiser percorrer a matriz de objetos com a função de seta:
let arr=[{name:'john',age:50},{name:'clark',age:19},{name:'mohan',age:26}];
arr.forEach((person)=>{
console.log('i am '+person.name+' and i am '+person.age+ ' old');
})
Ao iterar em um array, muitas vezes podemos realizar um dos seguintes objetivos:
Queremos fazer uma iteração sobre o array e criar um novo array:
Array.prototype.map
Queremos iterar pelo array e não criar um novo array:
Array.prototype.forEach
for..of
loop
No JS existem muitas maneiras de realizar esses dois objetivos. No entanto, alguns são mais conventivos do que outros. Abaixo você pode encontrar alguns métodos comumente usados (o imo mais conventiente) para realizar iteração de array em javascript.
Map
map()
é uma função localizada em Array.prototype
que pode transformar todos os elementos de um array e então retorna um new array. map()
recebe como argumento uma função de retorno de chamada e funciona da seguinte maneira:
let arr = [1, 2, 3, 4, 5];
let newArr = arr.map((element, index, array) => {
return element * 2;
})
console.log(arr);
console.log(newArr);
O retorno de chamada que passamos para map()
como um argumento é executado para cada elemento. Em seguida, uma matriz é retornada, que tem o mesmo tamanho da matriz original. Nesse novo elemento de matriz é transformado pela função de retorno de chamada passada como um argumento para map()
.
A diferença distinta entre map
e outro mecanismo de loop como forEach
e um loop for..of
é quemap
retorna como nova matriz e deixa a matriz antiga intacta (exceto se você explicitamente manipulá-la com pensa como splice
).
Observe também que o retorno de chamada da função map
fornece como segundo argumento o número do índice da iteração atual. Além disso, o terceiro argumento fornece o array no qual map
foi chamado. Às vezes, essas propriedades podem ser muito úteis.
forEach
forEach
é uma função que está localizada em Array.prototype
, que recebe uma função de callback como argumento. Em seguida, ele executa essa função de retorno de chamada para todos os elementos da matriz. Em contraste com a função map()
, a função forEach não retorna nada (undefined
). Por exemplo:
let arr = [1, 2, 3, 4, 5];
arr.forEach((element, index, array) => {
console.log(element * 2);
if (index === 4) {
console.log(array)
}
// index, and oldArray are provided as 2nd and 3th argument by the callback
})
console.log(arr);
Assim como a função map
, o retorno de chamada forEach
fornece como segundo argumento o número do índice da iteração atual. Além disso, o terceiro argumento fornece o array no qual forEach
foi chamado.
for..of
O loop for..of
faz um loop em todos os elementos de uma matriz (ou qualquer outro objeto iterável). Funciona da seguinte maneira:
let arr = [1, 2, 3, 4, 5];
for(let element of arr) {
console.log(element * 2);
}
No exemplo acima, element
representa um elemento da matriz e arr
é a matriz que desejamos fazer o loop. Não que o nome element
seja arbitrário e poderíamos ter escolhido qualquer outro nome como 'el' ou algo mais declarativo quando isso for aplicável.
Não confunda o loop for..in
com o loop for..of
. for..in
percorrerá todas as propriedades enumeráveis da matriz, enquanto o loop for..of
fará o loop apenas pelos elementos da matriz. Por exemplo:
let arr = [1, 2, 3, 4, 5];
arr.foo = 'foo';
for(let element of arr) {
console.log(element);
}
for(let element in arr) {
console.log(element);
}
Se você tem uma matriz massiva, você deve usar iterators
para ganhar alguma eficiência. Iteradores são uma propriedade de certas coleções JavaScript (como Map
, Set
, String
, Array
). Mesmo, for..of
usa iterator
por baixo do capô.
Iteradores melhoram a eficiência permitindo que você consuma os itens em uma lista, um de cada vez, como se fossem um fluxo. O que torna um iterador especial é como ele percorre uma coleção. Outros loops precisam carregar a coleção inteira na frente para iterar sobre ela, enquanto um iterador só precisa saber a posição atual na coleção.
Você acessa o item atual chamando o método next
do iterador. O próximo método retornará o value
do item atual e um boolean
para indicar quando você chegou ao final da coleção. A seguir, um exemplo de criação de um iterador de uma matriz.
Transforme sua matriz regular em iterador usando o método values()
desta forma:
const myArr = [2,3,4]
let it = myArr.values();
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
Você também pode transformar sua matriz regular em iterador usando Symbol.iterator
assim:
const myArr = [2,3,4]
let it = myArr[Symbol.iterator]();
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
Você também pode transformar seu array
regular em um iterator
assim:
let myArr = [8, 10, 12];
function makeIterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{done: true};
}
};
};
var it = makeIterator(myArr);
console.log(it.next().value); // {value: 8, done: false}
console.log(it.next().value); // {value: 10, done: false}
console.log(it.next().value); // {value: 12, done: false}
console.log(it.next().value); // {value: undefined, done: true}
NOTA:
iterable
por padrão. Use for..in
nesse caso porque em vez de valores trabalha com chaves.Você pode ler mais sobre iteration protocol
here .
var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
console.log("Index" + index);
console.log("Element" + item);
})
// Looping through arrays using foreach ES6 way
var data = new Array(1,2,3,4,5);
data.forEach((val,index) => {
console.log("index :",index); // index
console.log("value :", val); // value
});
Você pode usar a API forEach () (fornecida pelo Javascript) que aceita uma função como um retorno de chamada e é executada uma vez para cada elemento presente dentro da matriz.
https://fullstackgeek.blogspot.com/2019/01/arrays-in-javascript-part-2.html
Eu venho de python e achei isso muito mais claro.
theArray sendo a matriz, sendo a instância o elemento da matriz
for(let instance of theArray)
{
console.log("The instance",instance);
}
ou
for( instance in theArray)
{
console.log("The instance",instance);
}
comparado a:
theArray.forEach(function(instance) {
console.log(instance);
});
mas no final do dia ambos estão fazendo a mesma coisa
Se você quiser manter seu código da maneira funcional, use o mapa:
theArray.map(instance => do_something);
Desta forma, você irá gerar nova matriz para operação futura e irá ignorar qualquer efeito colateral indesejável.
Se você quiser usar forEach()
, será parecido com -
theArray.forEach ( element => {
console.log(element);
});
Se você quiser usar for()
, será parecido com -
for(let idx = 0; idx < theArray.length; idx++){
let element = theArray[idx];
console.log(element);
}