Loop através de uma matriz em JavaScript

3147

Em Java, você pode usar um forloop para percorrer objetos em uma matriz da seguinte maneira:

String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
    // Do something
}

Você pode fazer o mesmo em JavaScript?

Mark Szymanski
fonte
5
Ok, então estou um pouco confuso, é bom usar o loop for aprimorado quando você estiver acessando os objetos? E usar um seqüencial para preencher um? Isso está correto?
Mark Szymanski
45
não, é realmente simples, os objetos de matriz têm índices numéricos; portanto, você deseja iterar sobre esses índices na ordem numérica, um loop sequencial garante que o loop aprimorado enumere as propriedades do objeto, sem uma ordem específica, e também as propriedades herdadas. .. para iteração sobre matrizes laços seqüenciais são sempre recomendável ...for-in
CMS
2
relacionado - stackoverflow.com/questions/5349425/…
jondavidjohn
6
jsben.ch/#/Q9oD5 <= Aqui, um valor de referência de um monte de soluções para looping através de matrizes
EscapeNetscape
3
@ CM Não, não é realmente simples. É realmente simples em qualquer outro idioma. É ridiculamente complexo em JS, onde você tem ine ofque pode ser usado e fazer coisas diferentes. Então você também tem forEacho loop baseado em índices feios e irritantes. Qualquer outra linguagem moderna torna fácil e direto o loop de uma coleção, sem surpresas ou confusão. JS poderia também, mas não.
Jpmc26

Respostas:

3964

Você tem várias opções:

1. forLoop sequencial :

var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
    console.log(myStringArray[i]);
    //Do something
}

Prós

  • Funciona em todos os ambientes
  • Você pode usar breake continueinstruções de controle de fluxo

Contras

  • Muito detalhado
  • Imperativo
  • Fácil de ter erros de um por um (às vezes também chamado de erro no poste )

2. Array.prototype.forEach

A especificação ES5 introduziu muitos métodos de matriz benéficos, um deles, Array.prototype.forEache fornece uma maneira concisa de iterar sobre uma matriz:

const array = ["one", "two", "three"]
array.forEach(function (item, index) {
  console.log(item, index);
});

Sendo quase dez anos quando a especificação ES5 foi lançada (dezembro de 2009), ela foi implementada por quase todos os mecanismos modernos nos ambientes desktop, servidor e móvel, por isso é seguro usá-los.

E com a sintaxe da função de seta ES6, é ainda mais sucinto:

array.forEach(item => console.log(item));

As funções de seta também são amplamente implementadas, a menos que você planeje suportar plataformas antigas (por exemplo, IE11); você também está seguro para ir.

Prós

  • Muito curto e sucinto.
  • Declarativo

Contras

  • Não é possível usar break/continue

Normalmente, você pode substituir a necessidade breakde loops imperativos filtrando os elementos da matriz antes de iterá-los, por exemplo:

array.filter(item => item.condition < 10)
     .forEach(item => console.log(item))

Lembre-se de que, se você estiver iterando uma matriz para criar outra matriz a partir dela , deve usar map, já vi esse anti-padrão tantas vezes.

Anti-padrão:

const numbers = [1,2,3,4,5], doubled = [];

numbers.forEach((n, i) => { doubled[i] = n * 2 });

Caso de uso adequado do mapa :

const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);

console.log(doubled);

Além disso, se você estiver tentando reduzir a matriz para um valor, por exemplo, deseja somar uma matriz de números, use o método de redução .

Anti-padrão:

const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });

O uso adequado de reduzir :

const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);

console.log(sum);

3. for-ofdeclaração ES6

O padrão ES6 introduz o conceito de objetos iteráveis ​​e define uma nova construção para atravessar dados, a for...ofinstrução

Esta declaração funciona para qualquer tipo de objeto iterável e também para geradores (qualquer objeto que tenha uma [Symbol.iterator]propriedade).

Os objetos de matriz são iteráveis ​​internos por definição no ES6, para que você possa usar esta instrução neles:

let colors = ['red', 'green', 'blue'];
for (const color of colors){
    console.log(color);
}

Prós

  • Pode iterar sobre uma grande variedade de objetos.
  • Pode usar instruções de controle de fluxo normais ( break/ continue).
  • Útil para iterar valores serialmente assíncronos.

Contras

Não use for...in

O @zipcodeman sugere o uso da for...ininstrução, mas para iterar matrizes for-indeve ser evitado, essa instrução deve enumerar as propriedades do objeto.

Não deve ser usado para objetos do tipo matriz, porque:

  • A ordem da iteração não é garantida; os índices da matriz não podem ser visitados em ordem numérica.
  • Propriedades herdadas também são enumeradas.

O segundo ponto é que ele pode causar muitos problemas, por exemplo, se você estender o Array.prototypeobjeto para incluir um método lá, essa propriedade também será enumerada.

Por exemplo:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
    console.log(array[i]);
}

O código acima consola o log "a", "b", "c" e "foo!".

Isso será particularmente um problema se você usar alguma biblioteca que depende muito do aumento de protótipos nativos (como o MooTools, por exemplo).

A for-indeclaração, como eu disse antes, existe para enumerar as propriedades do objeto, por exemplo:

var obj = {
    "a": 1,
    "b": 2,
    "c": 3
};

for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) { 
        // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
        console.log("prop: " + prop + " value: " + obj[prop])
    }
}

No exemplo acima, o hasOwnPropertymétodo permite que você enumere apenas propriedades próprias , é isso, apenas as propriedades que o objeto possui fisicamente, nenhuma propriedade herdada.

Eu recomendo que você leia o seguinte artigo:

CMS
fonte
21
Esta é a razão (pelo próprio CMS) stackoverflow.com/questions/1885317/…
OscarRyz
15
@ DoubleGras, acho que é uma opinião que não é compartilhada por todos. Veja: stackoverflow.com/questions/5752906/… ou groups.google.com/forum/?fromgroups#!topic/jsmentors/…
Matthijs Wessels
3
Alguém pensando que você precisa armazenar em cache o comprimento ... Por favor, veja minha resposta, você nem precisa acessá-lo uma única vez, muito menos armazená-lo: for (var i = 0, item; item = myStringArray [i]; i ++) {/ * use item here * /}
Stijn de Witt
15
@StijndeWitt Não, porque que as quebras se você tiver quaisquer "Falsey" valores em sua matriz: false, undefined, 0, "", NaN.
Phrogz
6
jsperf.com/caching-array-length/4 Aqui está um teste para ver se vale a pena armazenar em cache o comprimento de uma matriz em um loop Javascript
Enrico
1115

Sim, supondo que sua implementação inclua o recurso for...of introduzido no ECMAScript 2015 (a versão "Harmony")) ... que é uma suposição bastante segura atualmente.

Funciona assim:

// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
  // ... do something with s ...
}

Ou melhor ainda, já que o ECMAScript 2015 também fornece variáveis ​​com escopo de bloco:

// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
  // ... do something with s ...
}
// s is no longer defined here

(A variável sé diferente em cada iteração, mas ainda pode ser declarada constdentro do corpo do loop, desde que não seja modificada lá.)

Uma observação sobre matrizes esparsas: uma matriz em JavaScript pode na verdade não armazenar tantos itens quanto os relatados por ela length; esse número relatado é simplesmente um maior que o índice mais alto no qual um valor é armazenado. Se o array contiver menos elementos do que o indicado pelo seu comprimento, é considerado esparso . Por exemplo, é perfeitamente legítimo ter uma matriz com itens apenas nos índices 3, 12 e 247; o lengthde uma matriz desse tipo é relatado como 248, embora esteja armazenando apenas 3 valores. Se você tentar acessar um item em qualquer outro índice, a matriz parecerá ter o undefinedvalor lá. Portanto, quando você deseja "fazer um loop" de uma matriz, você tem uma pergunta a ser respondida: deseja fazer um loop em todo o intervalo indicado pelo comprimento e processoundefineds para quaisquer elementos ausentes ou você deseja processar apenas os elementos realmente presentes? Existem muitos aplicativos para ambas as abordagens; depende apenas para o que você está usando a matriz.

Se você iterar sobre uma matriz com for.. of, o corpo do loop será executado lengthvezes e a variável de controle do loop será definida como undefinedpara quaisquer itens que não estejam realmente presentes na matriz. Dependendo dos detalhes do seu código "faça algo com", esse comportamento pode ser o que você deseja, mas se não, você deve usar uma abordagem diferente.

Claro, alguns desenvolvedores não têm escolha a não ser usar uma abordagem diferente de qualquer maneira, porque por alguma razão eles estão alvejando uma versão do JavaScript que ainda não suporta for... of.

Desde que sua implementação JavaScript seja compatível com a edição anterior da especificação ECMAScript (que exclui, por exemplo, versões do Internet Explorer anteriores à 9), você pode usar o Array#forEachmétodo iterador em vez de um loop. Nesse caso, você passa uma função a ser chamada em cada item da matriz:

var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) { 
     // ... do something with s ...
} );

Ao contrário de for... of, .forEachapenas chama a função para elementos que estão realmente presentes na matriz. Se for aprovada nossa matriz hipotética com três elementos e um comprimento de 248, ela chamará a função apenas três vezes, e não 248 vezes. Também distingue entre elementos ausentes e elementos que estão realmente configurados para undefined; para o último, ainda chamará a função, passando undefinedcomo argumento. Se isto é como você deseja lidar com matrizes esparsas, .forEachpode ser o caminho a percorrer, mesmo se seus apoios intérprete for... of.

A opção final, que funciona em todas as versões do JavaScript, é um loop de contagem explícito . Você simplesmente conta de 0 a um a menos que o comprimento e usa o contador como um índice. O loop básico é assim:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  s = myStringArray[i];
  // ... do something with s ...
}

Uma vantagem dessa abordagem é que você pode escolher como lidar com matrizes esparsas; O código acima irá executar o corpo do loop do total de lengthvezes, com sconjunto para undefinedpor quaisquer elementos em falta, assim como for.. of. Se você preferir manipular apenas os elementos realmente presentes de uma matriz esparsa, como .forEach, você pode adicionar um inteste simples no índice:

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  if (i in myStringArray) {
    s = myStringArray[i];
    // ... do something with s ...
  }
}

A atribuição do valor do comprimento à variável local (em vez de incluir a myStringArray.lengthexpressão completa na condição do loop) pode fazer uma diferença significativa no desempenho, uma vez que ignora uma pesquisa de propriedade todas as vezes; usando o Rhino na minha máquina, a aceleração é de 43%.

Você pode ver o tamanho do cache realizado na cláusula de inicialização do loop, assim:

var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {

O loop de contagem explícita também significa que você tem acesso ao índice de cada valor, se desejar. O índice também é passado como um parâmetro extra para a função que você passa forEach, para que você também possa acessá-lo dessa maneira:

myStringArray.forEach( function(s, i) {
   // ... do something with s and i ...
});

for... ofnão fornece o índice associado a cada objeto, mas contanto que o objeto sobre o qual você está iterando seja realmente um Array( for.. offunciona para outros tipos iteráveis ​​que podem não ter esse método), você pode usar o Array #entries para alterá-lo para uma matriz de pares [index, item] e iterar sobre isso:

for (const [i, s] of myStringArray.entries()) {
  // ... do something with s and i ...
}

A sintaxe for... inmencionada por outros é para fazer um loop sobre as propriedades de um objeto; como uma matriz em JavaScript é apenas um objeto com nomes de propriedades numéricos (e uma lengthpropriedade atualizada automaticamente ), você pode, teoricamente, fazer um loop sobre uma matriz com ele. Mas o problema é que ele não se restringe aos valores das propriedades numéricas (lembre-se de que mesmo métodos são na verdade apenas propriedades cujo valor é um fechamento), nem é garantido que itere sobre aqueles em ordem numérica. Portanto, a sintaxe for... nãoin deve ser usada para fazer um loop pelas matrizes.

Mark Reed
fonte
21
Observe que alguns intérpretes (por exemplo, V8) armazenam em cache automaticamente o comprimento da matriz se o código for chamado tempo suficiente e detecta que o comprimento não é modificado pelo loop. Embora o tamanho do cache ainda seja bom, ele pode não fornecer um aumento de velocidade quando o seu código está sendo chamado várias vezes para realmente fazer a diferença.
Phrogz
2
@ mark-reed Você poderia explicar por que usou i in myStringArrayno seu exemplo? Como isso pode ser falso?
Denis V
2
@ DenisV: false. a=[1,2,3,4]; delete a[2]; for (j in a) { console.log(j); } as saídas 0, 1, 3 e 4. a.lengthainda são 5. #
Mark Reed
1
Eu não estou sugerindo for j in a. Estou demonstrando que a inverificação não é redundante, como você alegou, mostrando todos os índices e mostrando que existe um entre 0 e length-1que não existe. Eu também poderia ter acabado de imprimir 2 in a, o que é realmente false, apesar do fato de você ter dito que isso era impossível.
Mark Reed
2
@GrijeshChauhan - correto. Por exemplo, o IE até a versão 8 não é compatível. Veja esta pergunta .
Mark Reed
442

Você pode usar map, que é uma técnica de programação funcional que também está disponível em outras linguagens como Python e Haskell .

[1,2,3,4].map( function(item) {
     alert(item);
})

A sintaxe geral é:

array.map(func)

Em geral, funcseria necessário um parâmetro, que é um item da matriz. Mas, no caso do JavaScript, ele pode usar um segundo parâmetro, que é o índice do item, e um terceiro parâmetro, que é o próprio array.

O valor de retorno de array.mapé outra matriz, para que você possa usá-lo assim:

var x = [1,2,3,4].map( function(item) {return item * 10;});

E agora x é [10,20,30,40].

Você não precisa escrever a função em linha. Pode ser uma função separada.

var item_processor = function(item) {
      // Do something complicated to an item
}

new_list = my_list.map(item_processor);

o que seria equivalente a:

 for (item in my_list) {item_processor(item);}

Exceto que você não entende new_list.

hasen
fonte
7
Não, mas pode ser mais poderoso. verifique isto: joelonsoftware.com/items/2006/08/01.html
hasen
97
Esse exemplo em particular provavelmente é melhor implementado usando Array.forEach. mapé para gerar uma nova matriz.
harto
21
@hasen, o Array.prototype.mapmétodo faz parte do ECMAScript 5th Edition Standard, ainda não está disponível em todas as implementações (por exemplo, o IE não possui), também para iterar sobre uma matriz. Acho que o Array.prototype.forEachmétodo é mais semanticamente correto ... também, por favor ' t sugerem a for-na declaração, ver a minha resposta para mais detalhes :)
CMS
3
A diferença entre forEache mapé que o primeiro não retorna os resultados da iteração. map(às vezes aka collect, mas muito diferente de apply) é expressamente para transformar cada elemento de uma matriz em um resultado correspondente; é um mapeamento 1 para 1 , daí o nome. Faz parte de toda uma família de operações que inclui reduce(que produz um único resultado de toda a matriz) e filter(que produz um subconjunto da matriz original) e assim por diante. Considerando que forEachapenas faz algo com cada elemento, semântica não especificada.
Mark Reed
4
Voto negativo, porque se você não estiver mapeando algo, o uso de [] .map é enganador. [] .forEach faz sentido semântico e também passa os mesmos três argumentos para a função.
gengkev
120

Em JavaScript, não é aconselhável fazer um loop através de uma matriz com um loop for-in, mas é melhor usar um forloop como:

for(var i=0, len=myArray.length; i < len; i++){}

Também é otimizado ("armazenando em cache" o comprimento da matriz). Se você quiser saber mais, leia meu post sobre o assunto .

sebarmeli
fonte
2
myArray.forEach (function (obj) {}); ainda é o melhor
Jan Sverre
uma pequena melhoria: você poderia usar ++iem vez dei++
roberkules
14
++ié uma otimização da velha escola que compiladores modernos fazer por você em um loop desde há muito tempo atrás :) stackoverflow.com/a/1547433/1033348
ngryman
6
Você precisa ter cuidado ao usar esse loop. Comecei a usá-lo e tinha um bug difícil de rastrear por causa de um erro que cometi. Se você aninhar dois loops como este: jsfiddle.net/KQwmL/1 . Você deve ter o cuidado de nomear o var len diferentemente nos dois loops, caso contrário, o segundo loop substituirá o primeiro len.
Rui Marques
1
Rui Marques - você pode nomear sua variável i_stopou em i_endvez de len. É tão legível (se não mais!), E você naturalmente evitará esse tipo de problema (já que seu outro loop terá, por exemplo, j_stop).
Chip Hogg
119

for (vamos s de myStringArray) {

(Respondendo diretamente à sua pergunta: agora você pode!)

A maioria das outras respostas está correta, mas elas não mencionam (até o momento em que escrevemos) que o ECMA Script  6  2015 está trazendo um novo mecanismo para fazer a iteração, o for..ofloop.

Essa nova sintaxe é a maneira mais elegante de iterar uma matriz em javascript (desde que você não precise do índice de iteração).

Atualmente, ele funciona com Firefox 13+, Chrome 37+ e não funciona de maneira nativa com outros navegadores (consulte a compatibilidade do navegador abaixo). Felizmente, temos compiladores JS (como o Babel ) que nos permitem usar os recursos da próxima geração hoje.

Também funciona no Node (eu testei na versão 0.12.0).

Iterando uma matriz

// You could also use "let" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) { 
   console.log(letter); 
}

Iterando uma matriz de objetos

var band = [
  {firstName : 'John', lastName: 'Lennon'}, 
  {firstName : 'Paul', lastName: 'McCartney'}
];

for(var member of band){
  console.log(member.firstName + ' ' + member.lastName); 
}

Iterando um Gerador:

(exemplo extraído de https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of )

function* fibonacci() { // a generator function
  let [prev, curr] = [1, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  console.log(n);
  // truncate the sequence at 1000
  if (n >= 1000) {
    break;
  }
}

Tabela de compatibilidade: http://kangax.github.io/es5-compat-table/es6/#For..of loops

Spec: http://wiki.ecmascript.org/doku.php?id=harmony:iterators

}

Marlon Bernardes
fonte
Se você estiver usando o ES6, eu sugeriria em const svez devar s
joeytwiddle
Nos testes em grandes conjuntos, usando var s of arré quase o dobro (1,9x) o tempo de execução em relação ao uso de um simples contador for-loop e recuperação de elementos de índice em nodejs
theferrit32
Por que essas coisas estranhas na primeira e na última linha?
Peter Mortensen
91

Opera, Safari, Firefox e Chrome agora compartilham um conjunto de métodos Array aprimorados para otimizar muitos loops comuns.

Talvez você não precise de todos eles, mas eles podem ser muito úteis ou seriam se todos os navegadores os suportassem.

O Mozilla Labs publicou os algoritmos que eles e o WebKit usam, para que você possa adicioná-los você mesmo.

O filtro retorna uma matriz de itens que satisfazem alguma condição ou teste.

every retorna true se cada membro da matriz passa no teste.

alguns retornos verdadeiros se algum passar no teste.

O forEach executa uma função em cada membro da matriz e não retorna nada.

map é como forEach, mas retorna uma matriz dos resultados da operação para cada elemento.

Todos esses métodos assumem uma função para o primeiro argumento e têm um segundo argumento opcional, que é um objeto cujo escopo você deseja impor aos membros da matriz à medida que passam pela função.

Ignore-o até precisar.

indexOf e lastIndexOf localizam a posição apropriada do primeiro ou do último elemento que corresponde exatamente ao seu argumento.

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this))
                        return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what)
                    return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L)
                i= L-1;
            else
                if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what)
                    return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this))
                        return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p])
            ap[p]= p2[p];
    }
    return true;
})();
Kennebec
fonte
1
Adição: IE suporta forEach desde a versão 9, consulte forEach Método MSDN
rwitzel
75

Introdução

Desde que eu estive na faculdade, eu programei em Java, JavaScript, Pascal, ABAP , PHP, Progress 4GL, C / C ++ e, possivelmente, algumas outras linguagens em que não consigo pensar agora.

Embora todos tenham suas próprias idiossincrasias linguísticas, cada um desses idiomas compartilha muitos dos mesmos conceitos básicos. Tais conceitos incluem procedimentos / funções, IFdeclarações, FORloops e WHILEloops.


Um forlaço tradicional

Um forloop tradicional possui três componentes:

  1. A inicialização: executada antes da primeira execução do bloco de aparência
  2. A condição: verifica uma condição sempre que o bloco de loop é executado e sai do loop se falso
  3. A reflexão tardia: realizada sempre que o bloco de loop é executado

Esses três componentes são separados um do outro por um ;símbolo. O conteúdo de cada um desses três componentes é opcional, o que significa que o seguinte é o forloop mais mínimo possível:

for (;;) {
    // Do stuff
}

Obviamente, você precisará incluir um if(condition === true) { break; } ou um local if(condition === true) { return; }dentro desse forloop para que ele pare de funcionar.

Normalmente, porém, a inicialização é usada para declarar um índice, a condição é usada para comparar esse índice com um valor mínimo ou máximo, e a reflexão posterior é usada para incrementar o índice:

for (var i = 0, length = 10; i < length; i++) {
    console.log(i);
}

Usando um forloop tradicional para percorrer uma matriz

A maneira tradicional de percorrer uma matriz é esta:

for (var i = 0, length = myArray.length; i < length; i++) {
    console.log(myArray[i]);
}

Ou, se você preferir fazer um loop para trás, faça o seguinte:

for (var i = myArray.length - 1; i > -1; i--) {
    console.log(myArray[i]);
}

Existem, no entanto, muitas variações possíveis, como por exemplo esta:

for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
    console.log(value);
}

... ou este ...

var i = 0, length = myArray.length;
for (; i < length;) {
    console.log(myArray[i]);
    i++;
}

... ou este:

var key = 0, value;
for (; value = myArray[key++];){
    console.log(value);
}

O que funcionar melhor é em grande parte uma questão de gosto pessoal e do caso de uso específico que você está implementando.

Observe que cada uma dessas variações é suportada por todos os navegadores, incluindo os muito muito antigos!


Um whilelaço

Uma alternativa para um forloop é um whileloop. Para percorrer uma matriz, você pode fazer o seguinte:

var key = 0;
while(value = myArray[key++]){
    console.log(value);
}

Como forloops tradicionais , os whileloops são suportados até pelos navegadores mais antigos.

Além disso, observe que o loop while pode ser reescrito como um forloop. Por exemplo, o whileloop acima se comporta exatamente da mesma maneira que este forloop:

for(var key = 0; value = myArray[key++];){
    console.log(value);
}

For...in e for...of

Em JavaScript, você também pode fazer isso:

for (i in myArray) {
    console.log(myArray[i]);
}

Isso deve ser usado com cuidado, no entanto, uma vez que não se comporta da mesma forma que um forloop tradicional em todos os casos, e existem possíveis efeitos colaterais que precisam ser considerados. Consulte Por que usar "for ... in" com iteração de matriz é uma má idéia? para mais detalhes.

Como alternativa for...in, agora também existe for...of. O exemplo a seguir mostra a diferença entre um for...ofloop e um for...inloop:

var myArray = [3, 5, 7];
myArray.foo = "hello";

for (var i in myArray) {
  console.log(i); // logs 0, 1, 2, "foo"
}

for (var i of myArray) {
  console.log(i); // logs 3, 5, 7
}

Além disso, é necessário considerar que nenhuma versão do Internet Explorer suporta for...of( Edge 12+ ) e que for...inrequer pelo menos o Internet Explorer 10.


Array.prototype.forEach()

Uma alternativa para for-loops é Array.prototype.forEach(), que usa a seguinte sintaxe:

myArray.forEach(function(value, key, myArray) {
    console.log(value);
});

Array.prototype.forEach() é suportado por todos os navegadores modernos, bem como pelo Internet Explorer 9 e posterior.


Bibliotecas

Finalmente, muitas bibliotecas de utilidades também têm suas próprias foreachvariações. AFAIK, os três mais populares são os seguintes:

jQuery.each(), em jQuery :

$.each(myArray, function(key, value) {
    console.log(value);
});

_.each(), em Underscore.js :

_.each(myArray, function(value, key, myArray) {
    console.log(value);
});

_.forEach(), no Lodash.js :

_.forEach(myArray, function(value, key) {
    console.log(value);
});
John Slegers
fonte
68

Use o loop while ...

var i=0, item, items = ['one','two','three'];
while(item = items[i++]){
    console.log(item);
}

logs: 'um', 'dois', 'três'

E para a ordem inversa, um loop ainda mais eficiente

var items = ['one','two','three'], i = items.length;
while(i--){
    console.log(items[i]);
}

logs: 'três', 'dois', 'um'

Ou o forlaço clássico

var items = ['one','two','three']
for(var i=0, l = items.length; i < l; i++){
    console.log(items[i]);
}

logs: 'um', 'dois', 'três'

Referência: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/

Timo Huovinen
fonte
21
O primeiro exemplo da sintaxe "while" não funcionará se algum dos elementos da matriz for falso.
Chris Cooper
2
... e esse loop while é equivalente a: for (var i = 0, item; item = itens [i]; i ++), o que elimina a necessidade de declarar as variáveis ​​de índice e item de antemão ...
Stijn de Witt
39

Se você deseja uma maneira concisa de escrever um loop rápido e pode iterar ao contrário:

for (var i=myArray.length;i--;){
  var item=myArray[i];
}

Isso tem o benefício de armazenar em cache o comprimento (semelhante for (var i=0, len=myArray.length; i<len; ++i)e diferente for (var i=0; i<myArray.length; ++i)) e ter menos caracteres para digitar.

Existem até momentos em que você deve iterar ao contrário, como ao iterar em uma NodeList ativa, na qual planeja remover itens do DOM durante a iteração.

Phrogz
fonte
16
Para as pessoas que não entendem o que é tão engenhoso: A expressão i-- é avaliada primeiro e permite que o loop continue quando não é falso ... Depois, o contador é diminuído. Assim que eu ficar zero, ele sairá do loop, pois zero é um valor falso em Javascript.
Stijn de Witt
5
falsificar? Você quer dizer falsey. Vamos todos vara a terminologia adequada à confusão evitar;)
danwellman
4
Vi o termo falsear sendo usado por pessoas que considero gurus. Se é bom o suficiente para eles, é bom o suficiente para mim. Também fiquei desapontado ao ver que meu comentário realmente ontopico e que adiciona explicações / insights recebe 0 votos positivos, mas o comentário que aponta um termo no meu comentário recebe 4. Ah, bem, acho que é apenas uma questão de prioridades.
Stijn de Witt
"Armazenando em cache o comprimento"? O comprimento é armazenado como um número inteiro na matriz, não é medido sempre que você o acessa. Aqui não há benefício em copiar o valor do comprimento para outra variável.
Mouscellaneous
1
@ Diversos Hoje em dia certamente não há; Nos últimos anos, as iterações de JavaScript em cache, o tamanho do lado do JavaScript (em vez de alcançar a implementação), foi um claro ganho de desempenho (ao microotimizar). Por exemplo, for (var i=0,len=array.length;i<len;++i)era um loop comum e sensível para escrever.
precisa saber é
36

Alguns casos de uso de loop através de uma matriz da maneira de programação funcional em JavaScript:

1. Basta percorrer uma matriz

const myArray = [{x:100}, {x:200}, {x:300}];

myArray.forEach((element, index, array) => {
    console.log(element.x); // 100, 200, 300
    console.log(index); // 0, 1, 2
    console.log(array); // same myArray object 3 times
});

Nota: Array.prototype.forEach () não é uma maneira funcional, estritamente falando, pois a função que assume como parâmetro de entrada não deve retornar um valor, que, portanto, não pode ser considerado como uma função pura.

2. Verifique se algum dos elementos de uma matriz passa em um teste

const people = [
    {name: 'John', age: 23}, 
    {name: 'Andrew', age: 3}, 
    {name: 'Peter', age: 8}, 
    {name: 'Hanna', age: 14}, 
    {name: 'Adam', age: 37}];

const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true

3. Transforme em uma nova matriz

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]

Nota: O método map () cria uma nova matriz com os resultados da chamada de uma função fornecida em todos os elementos da matriz de chamada.

4. Resuma uma propriedade específica e calcule sua média

const myArray = [{x:100}, {x:200}, {x:300}];

const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300

const average = sum / myArray.length;
console.log(average); // 200

5. Crie uma nova matriz com base no original, mas sem modificá-lo

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => {
    return {
        ...element,
        x: element.x * 2
    };
});

console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]

6. Conte o número de cada categoria

const people = [
    {name: 'John', group: 'A'}, 
    {name: 'Andrew', group: 'C'}, 
    {name: 'Peter', group: 'A'}, 
    {name: 'James', group: 'B'}, 
    {name: 'Hanna', group: 'A'}, 
    {name: 'Adam', group: 'B'}];

const groupInfo = people.reduce((groups, person) => {
    const {A = 0, B = 0, C = 0} = groups;
    if (person.group === 'A') {
        return {...groups, A: A + 1};
    } else if (person.group === 'B') {
        return {...groups, B: B + 1};
    } else {
        return {...groups, C: C + 1};
    }
}, {});

console.log(groupInfo); // {A: 3, C: 1, B: 2}

7. Recupere um subconjunto de uma matriz com base em critérios específicos

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}] 

Nota: O método filter () cria uma nova matriz com todos os elementos que passam no teste implementado pela função fornecida.

8. Classifique uma matriz

const people = [
  { name: "John", age: 21 },
  { name: "Peter", age: 31 },
  { name: "Andrew", age: 29 },
  { name: "Thomas", age: 25 }
];

let sortByAge = people.sort(function (p1, p2) {
  return p1.age - p2.age;
});

console.log(sortByAge);

insira a descrição da imagem aqui

9. Encontre um elemento em uma matriz

const people = [ {name: "john", age:23},
                {name: "john", age:43},
                {name: "jim", age:101},
                {name: "bob", age:67} ];

const john = people.find(person => person.name === 'john');
console.log(john);

insira a descrição da imagem aqui

O método Array.prototype.find () retorna o valor do primeiro elemento na matriz que satisfaz a função de teste fornecida.

Referências

Yuci
fonte
30

Existe uma maneira de fazer isso em que você tem muito pouco escopo implícito em seu loop e elimina variáveis ​​extras.

var i = 0,
     item;

// note this is weak to sparse arrays or falsey values
for ( ; item = myStringArray[i++] ; ){ 
    item; // This is the string at the index.
}

Ou se você realmente deseja obter o ID e ter um forloop realmente clássico :

var i = 0,
    len = myStringArray.length; // cache the length

for ( ; i < len ; i++ ){
    myStringArray[i]; // Don't use this if you plan on changing the length of the array
}

Navegadores modernos todos os métodos de suporte de iterador forEach, map, reduce, filtere uma série de outros métodos no protótipo matriz .

Gabriel
fonte
3
Observe que alguns intérpretes (por exemplo, V8) armazenam em cache automaticamente o comprimento da matriz se o código for chamado tempo suficiente e detectar que o comprimento não é modificado pelo loop.
Phrogz
Obrigado pela informação @Phrogz, é verdade que existem muitas otimizações que a VM pode fazer, mas como os navegadores mais antigos não têm isso, ainda seria uma boa prática otimizar, pois é muito barato.
Gabriel
1
@ Gabriel: Por quê? Dê exemplos do mundo real mostrando que não armazenar em cache o comprimento é realmente um gargalo de desempenho. Eu sigo a abordagem 'otimização prematura é a raiz de todo mal'. Vou consertar isso um loop que realmente coloca um problema uma vez que eu encontrá-lo ...
Stijn de Witt
1
@StijndeWitt imo é apenas uma questão de estilo. Honestamente, eu nem uso mais para loops, ao invés disso, confio no sublinhado para coisas como _.each, _.map etc. para fazer essas coisas. Quando escrevi loops como esse, armazenei em cache o comprimento principalmente para que todas as minhas declarações de variáveis ​​estivessem em um só lugar, na parte superior da minha função. Seguir meus conselhos nesse sentido é irrelevante para qualquer aplicação do mundo real. A otimização prematura é muito ruim, mas se a otimização resultar de decisões estilísticas, não acho que realmente importe.
Gabriel
1
@ Gabriel Eu acredito que o JavaScript já suporta a função de mapa em matrizes, não é necessário introduzir uma biblioteca adicional para isso.
Noz
28

Existem várias maneiras de percorrer a matriz em JavaScript.

Loop genérico:

var i;
for (i = 0; i < substr.length; ++i) {
    // Do something with `substr[i]`
}

ES5's forEach:

substr.forEach(function(item) {
    // Do something with `item`
});

jQuery.each:

jQuery.each(substr, function(index, item) {
    // Do something with `item` (or `this` is also `item` if you like)
});

Dê uma olhada nisto para obter informações detalhadas ou você também pode verificar o MDN para executar um loop em uma matriz em JavaScript e usar o jQuery e verificar o jQuery para cada um .

RizN81
fonte
27

Eu recomendaria completamente o uso da biblioteca underscore.js . Ele fornece várias funções que você pode usar para iterar sobre matrizes / coleções.

Por exemplo:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...
Andrew Thomson
fonte
7
Para os novos descobridores dessa questão, eu gostaria de destacar Lo-Dash , um sucessor espiritual do Underscore que o aprimora de várias maneiras.
Mark Reed
3
Por que usar underscorese o ECMA-262 foi adicionado ao forEachmethor. O código nativo é sempre melhor.
Walter Chapilliquen - KaTriX Os Melhores Vídeos da Internet
27

Loop de matriz:

for(var i = 0; i < things.length; i++){
    var thing = things[i];
    console.log(thing);
}

Loop de objeto:

for(var prop in obj){
    var propValue = obj[prop];
    console.log(propValue);
}
bzim
fonte
27

Sim , você pode fazer o mesmo em JavaScript usando um loop, mas não se limitando a isso, existem várias maneiras de fazer um loop sobre matrizes em JavaScript. Imagine que você tem esse array abaixo e gostaria de fazer um loop sobre ele:

var arr = [1, 2, 3, 4, 5];

Estas são as soluções:

1) For loop

Um forloop é uma maneira comum de percorrer matrizes em JavaScript, mas não são consideradas as soluções mais rápidas para matrizes grandes:

for (var i=0, l=arr.length; i<l; i++) {
  console.log(arr[i]);
}

2) Enquanto loop

Um loop while é considerado a maneira mais rápida de percorrer longas matrizes, mas geralmente é menos usado no código JavaScript:

let i=0;

while (arr.length>i) {
    console.log(arr[i]);
    i++;
}

3) Faça enquanto
A do whileestiver fazendo a mesma coisa que whilecom alguma diferença de sintaxe como abaixo:

let i=0;
do {
  console.log(arr[i]);
  i++;
}
while (arr.length>i);

Essas são as principais maneiras de fazer loops de JavaScript, mas existem mais algumas maneiras de fazer isso.

Também usamos um for inloop para repetir objetos em JavaScript.

Também olhar para os map(), filter(), reduce()funções, etc. em uma matriz em JavaScript. Eles podem fazer as coisas muito mais rápido e melhor do que usar whilee for.

Este é um bom artigo, se você quiser saber mais sobre as funções assíncronas sobre matrizes em JavaScript.

Atualmente, a programação funcional tem causado bastante impacto no mundo do desenvolvimento. E por um bom motivo: as técnicas funcionais podem ajudá-lo a escrever um código mais declarativo que é mais fácil de entender rapidamente, refatorar e testar.

Um dos pilares da programação funcional é o uso especial de listas e operações de lista. E essas coisas são exatamente como são: matrizes de coisas e o que você faz com elas. Mas a mentalidade funcional os trata de maneira um pouco diferente do que você poderia esperar.

Este artigo analisará atentamente o que eu gosto de chamar de operações da lista dos "três grandes": mapear, filtrar e reduzir. Envolvê-lo nessas três funções é um passo importante para poder escrever um código funcional limpo e abre as portas para as técnicas extremamente poderosas de programação funcional e reativa.

Isso também significa que você nunca precisará escrever um loop for novamente.

Leia mais >> aqui :

Alireza
fonte
Existe realmente uma diferença de desempenho antes de um loop for e um while durante a iteração em uma matriz? Eu estava sob a impressão das diferenças eram principalmente sintática
karité
24

Se alguém estiver interessado no lado do desempenho dos vários mecanismos disponíveis para iterações de matriz, preparei os seguintes testes JSPerf:

https://jsperf.com/fastest-array-iterator

Resultados de desempenho

Resultados:

O for()iterador tradicional é de longe o método mais rápido, especialmente quando usado com o comprimento da matriz em cache .

let arr = [1,2,3,4,5];

for(let i=0, size=arr.length; i<size; i++){
    // Do something
}

A Array.prototype.forEach()e os Array.prototype.map()métodos são as aproximações mais lentas, provavelmente como uma consequência da sobrecarga de chamada de função .

colxi
fonte
é melhor usar em i = i +1vez dei++
DarckBlezzer
2
Pode ser melhorado: Use: ++ i em vez de i ++, isso evitará um objeto temporário. Portanto, reduz o uso de memória e o tempo da CPU (não é necessária alocação)!
PowerStat
@PowerStat você pode fornecer um link ou referência sobre isso? Eu nunca aheard sobre isso, parece interessante ...
colxi
1
@colxi Para coisas tão interessantes, você deve ler o hardcore C ++ de Herb Sutter e Scott Meyers. O item ++ i vs i ++ é do livro: C ++ excepcional: 47 quebra-cabeças de engenharia, problemas de programação e soluções - acho que você também pode encontrá-lo no gotw.ca, mas pode ser comprovado para todas as linguagens de programação.
PowerStat
21

Se você estiver usando a biblioteca jQuery, considere usar http://api.jquery.com/jQuery.each/

A partir da documentação:

jQuery.each( collection, callback(indexInArray, valueOfElement) )

Retorna: Objeto

Descrição: uma função iteradora genérica, que pode ser usada para iterar perfeitamente objetos e matrizes. Matrizes e objetos semelhantes a matrizes com uma propriedade length (como o objeto de argumentos de uma função) são iterados pelo índice numérico, de 0 a length-1. Outros objetos são iterados por meio de suas propriedades nomeadas.

A $.each()função não é a mesma que $(selector).each(), que é usada para iterar, exclusivamente, sobre um objeto jQuery. A $.each() função pode ser usada para iterar sobre qualquer coleção, seja um mapa (objeto JavaScript) ou uma matriz. No caso de uma matriz, o retorno de chamada recebe um índice da matriz e um valor correspondente da matriz a cada vez. (O valor também pode ser acessado por meio da thispalavra - chave, mas o Javascript sempre o thisagrupará como um valor Objectmesmo que seja uma sequência simples ou um valor numérico.) O método retorna seu primeiro argumento, o objeto que foi iterado.

justingordon
fonte
9
jQuery para tudo?
Exceção
6
Concordou com Exceção. Não subestime o impacto de dependências extras. Eu aconselharia contra isso, exceto no código que já está usando muito o jQuery de qualquer maneira.
Stijn de Witt
2
Atualização: hoje em dia, você pode usar Array.forEach para obter o mesmo efeito com matrizes nativas.
Stijn de Witt
21

Ainda não vi essa variação, que eu pessoalmente gosto mais:

Dada uma matriz:

var someArray = ["some", "example", "array"];

Você pode fazer um loop sobre ele sem acessar a propriedade length:

for (var i=0, item; item=someArray[i]; i++) {
  // item is "some", then "example", then "array"
  // i is the index of item in the array
  alert("someArray[" + i + "]: " + item);
}

Veja este JsFiddle demonstrando que: http://jsfiddle.net/prvzk/

Isso funciona apenas para matrizes que não são esparsas. Significando que realmente existe um valor em cada índice da matriz. No entanto, descobri que na prática quase nunca uso matrizes esparsas em JavaScript ... Nesses casos, geralmente é muito mais fácil usar um objeto como um mapa / hashtable. Se você possui uma matriz esparsa e deseja fazer um loop acima de 0 .. length-1, precisa da construção for (var i = 0; i <someArray.length; ++ i), mas ainda precisa de umif loop interno para verificar se o elemento no índice atual está realmente definido.

Além disso, como o CMS menciona em um comentário abaixo, você pode usá-lo apenas em matrizes que não contêm valores falsos. A matriz de strings do exemplo funciona, mas se você tiver strings vazias ou números 0 ou NaN, etc., o loop será interrompido prematuramente. Mais uma vez, na prática, isso quase nunca é um problema para mim, mas é algo a ter em mente, o que torna um ciclo para pensar antes de usá-lo ... Isso pode desqualificá-lo para algumas pessoas :)

O que eu gosto nesse loop é:

  • É curto escrever
  • Não é necessário acessar (e muito menos armazenar em cache) a propriedade length
  • O item a ser acessado é automaticamente definido no corpo do loop sob o nome que você escolhe.
  • Combina naturalmente com array.push e array.splice para usar matrizes como listas / pilhas

A razão pela qual isso funciona é que a especificação da matriz exige que, quando você ler um item de um índice> = o comprimento da matriz, ele retorne indefinido. Quando você escreve em um local, ele realmente atualiza o comprimento.

Para mim, essa construção emula mais de perto a sintaxe do Java 5 que eu amo:

for (String item : someArray) {
}

... com o benefício adicional de conhecer também o índice atual dentro do loop

Stijn de Witt
fonte
14
Observe que com esta abordagem o loop irá parar logo que encontrar um valor Falsey , como uma cadeia vazia, 0, false, NaN, nullou undefined, mesmo antes de iatingir o tamanho, por exemplo: jsfiddle.net/prvzk/1
CMS
3
A condição do loop pode ser (item=someArray[i]) !== undefined.
daniel1426
18

Existe um método para iterar apenas as propriedades do próprio objeto, sem incluir as do protótipo:

for (var i in array) if (array.hasOwnProperty(i)) {
    // Do something with array[i]
}

mas ainda iterará nas propriedades definidas personalizadas.

Em JavaScript, qualquer propriedade customizada pode ser atribuída a qualquer objeto, incluindo uma matriz.

Se alguém quiser iterar sobre uma matriz poupada, for (var i = 0; i < array.length; i++) if (i in array)ou array.forEachcom, es5shimdeve ser usado.

kirilloid
fonte
E que tal usar for (var i in array) if (++i)?
22614 Daniel Sokolowski
15

Existem algumas maneiras de fazer isso em JavaScript. Os dois primeiros exemplos são exemplos de JavaScript. O terceiro utiliza uma biblioteca JavaScript, ou seja, o jQuery fazendo uso da .each()função.

var myStringArray = ["hello", "World"];
for(var i in myStringArray) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
for (var i=0; i < myStringArray.length; i++) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
$.each(myStringArray, function(index, value){
  alert(value);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Shubham Khatri
fonte
for...indeve ser evitado para objetos do tipo Array
brk
15

A maneira mais elegante e rápida

var arr = [1, 2, 3, 1023, 1024];
for (var value; value = arr.pop();) {
    value + 1
}

http://jsperf.com/native-loop-performance/8


Editado (porque eu estava errado)


Comparando métodos para fazer loop em uma matriz de 100000 itens e executar uma operação mínima com o novo valor a cada vez.

Preparação:

<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script>
    Benchmark.prototype.setup = function() {
        // Fake function with minimal action on the value
        var tmp = 0;
        var process = function(value) {
            tmp = value; // Hold a reference to the variable (prevent engine optimisation?)
        };

        // Declare the test Array
        var arr = [];
        for (var i = 0; i < 100000; i++)
            arr[i] = i;
    };
</script>

Testes:

<a href="http://jsperf.com/native-loop-performance/16" 
   title="http://jsperf.com/native-loop-performance/16"
><img src="http://i.imgur.com/YTrO68E.png" title="Hosted by imgur.com" /></a>
molokoloco
fonte
Esse loop parece não seguir a ordem dos itens na matriz.
Deniz Ozger # 26/14
Meu teste estava errado. Está correto, mostrando todos os LOOPS agora. jsperf.com/native-loop-performance/16 #
molokoloco 27/03
@bergi está certo. Esse loop apaga a matriz à medida que passa por ela. Não é o que você deseja na maioria dos casos.
Stijn de Witt
4
quebra nos itens falsey.
Njzk2 29/07
12

A abordagem otimizada é armazenar em cache o comprimento da matriz e usar o padrão var único, inicializando todas as variáveis ​​com a palavra-chave var única.

var i, max, myStringArray = ["Hello","World"];
for (i = 0, max = myStringArray.length; i < max; i++) {
    alert(myStringArray[i]);
   //Do something
}

Se a ordem da iteração não importa, você deve tentar o loop reverso, é mais rápido, pois reduz o teste de condição de sobrecarga e o decremento está em uma instrução:

var i,myStringArray = ["item1","item2"];
for (i =  myStringArray.length; i--) {
    alert(myStringArray[i]);
}

ou melhor e mais limpo para usar while loop:

var myStringArray = ["item1","item2"],i = myStringArray.length;
while(i--) {
   // do something with fruits[i]
}
Zaheer Ahmed
fonte
12

Em JavaScript, existem muitas soluções para fazer um loop em uma matriz.

O código abaixo é popular

/** Declare inputs */
const items = ['Hello', 'World']

/** Solution 1. Simple for */
console.log('solution 1. simple for')

for (let i = 0; i < items.length; i++) {
  console.log(items[i])
}

console.log()
console.log()

/** Solution 2. Simple while */
console.log('solution 2. simple while')

let i = 0
while (i < items.length) {
  console.log(items[i++])
}

console.log()
console.log()

/** Solution 3. forEach*/
console.log('solution 3. forEach')

items.forEach(item => {
  console.log(item)
})

console.log()
console.log()

/** Solution 4. for-of*/
console.log('solution 4. for-of')

for (const item of items) {
  console.log(item)
}

console.log()
console.log()

Alongkorn Chetasumon
fonte
12

Se você deseja usar o jQuery, ele possui um bom exemplo em sua documentação:

 $.each([ 52, 97 ], function( index, value ) {
      alert( index + ": " + value );
 });
jj_
fonte
12

A melhor maneira, na minha opinião, é usar a função Array.forEach. Se você não pode usar isso, sugiro obter o polyfill do MDN. Para disponibilizá-lo, é certamente a maneira mais segura de interagir com uma matriz em JavaScript.

Array.prototype.forEach ()

Então, como outros sugeriram, é quase sempre o que você deseja:

var numbers = [1,11,22,33,44,55,66,77,88,99,111];
var sum = 0;
numbers.forEach(function(n){
  sum += n;
});

Isso garante que qualquer coisa que você precise no escopo do processamento da matriz permaneça dentro desse escopo e que esteja processando apenas os valores da matriz, não as propriedades do objeto e outros membros, e é isso que for .. faz.

Usando um estilo C regular for loop comum no funciona na maioria dos casos. É importante lembrar que tudo dentro do loop compartilha seu escopo com o restante do seu programa, o {} não cria um novo escopo.

Conseqüentemente:

var sum = 0;
var numbers = [1,11,22,33,44,55,66,77,88,99,111];

for(var i = 0; i<numbers.length; ++i){
  sum += numbers[i];
}

alert(i);

produzirá "11" - que pode ou não ser o que você deseja.

Um exemplo de jsFiddle em funcionamento: https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/

Espen
fonte
10

Não é 100% idêntico, mas semelhante:

   var myStringArray = ['Hello', 'World']; // array uses [] not {}
    for (var i in myStringArray) {
        console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
    }

Muhammad Alvin
fonte
1
Parece que isso funcionaria contra problemas semelhantes aos de outros usos em um objeto de matriz, pois as variáveis ​​de membro do protótipo também seriam capturadas pelo for.
Kzqai 18/04
9

Por exemplo, eu usei em um console do Firefox:

[].forEach.call(document.getElementsByTagName('pre'), function(e){ 
   console.log(e);
})
victorq10
fonte
9
var x = [4, 5, 6];
for (i = 0, j = x[i]; i < x.length; j = x[++i]) {
    console.log(i,j);
}

Muito mais limpo ...

staticd
fonte
Isso não é muito limpo em comparação com z.forEach(j => console.log(j));.
Sapphire_Brick
9

Resposta curta: sim. Você pode fazer isso:

var myArray = ["element1", "element2", "element3", "element4"];

for (i = 0; i < myArray.length; i++) {
  console.log(myArray[i]);
}

Em um console do navegador, você pode ver algo como "element1", "element2" etc., impresso.

Juanjo Salvador
fonte
9

Você pode usar Array.prototype.forEach(...):

var arr = ["apple", "banana", "cherry", "mango"];
arr.forEach((item, index)=>{
   //Some code...
});

Ou Array.prototype.map(...):

var arr = ["apple", "banana", "cherry", "mango"];
arr.map((item, index)=>{
   //Some code...
});

Ou o jquery ou o loop for mencionado anteriormente.

Sapphire_Brick
fonte