Cuidado:
a pergunta ainda se aplica aos
for…of
loops.> Não usefor…in
para iterar sobre uma matriz , use-o para iterar sobre as propriedades de um objeto. Dito isto, este
Entendo que a for…in
sintaxe básica do JavaScript se parece com isso:
for (var obj in myArray) {
// ...
}
Mas como obtenho o contador / índice de loop ?
Eu sei que provavelmente poderia fazer algo como:
var i = 0;
for (var obj in myArray) {
alert(i)
i++
}
Ou até o bom e velho:
for (var i = 0; i < myArray.length; i++) {
var obj = myArray[i]
alert(i)
}
Mas eu prefiro usar o for-in
loop mais simples . Eu acho que eles parecem melhores e fazem mais sentido.
Existe uma maneira mais simples ou mais elegante?
No Python, é fácil:
for i, obj in enumerate(myArray):
print i
javascript
for-loop
foreach
counter
hobbes3
fonte
fonte
alert(obj)
?Respostas:
for…in
itera sobre nomes de propriedades, não valores, e faz isso em uma ordem não especificada (sim, mesmo depois do ES6). Você não deve usá-lo para iterar sobre matrizes. Para eles, existe oforEach
método do ES5 que passa o valor e o índice para a função que você atribui:Ou ES6
Array.prototype.entries
, que agora tem suporte nas versões atuais do navegador:Para iterables em geral (onde você usaria um
for…of
loop em vez de afor…in
), no entanto, não há nada embutido:demonstração
Se você realmente quis dizer
for…in
- enumerando propriedades - seria necessário um contador adicional.Object.keys(obj).forEach
poderia funcionar, mas inclui apenas propriedades próprias ;for…in
inclui propriedades enumeráveis em qualquer lugar da cadeia de protótipos.fonte
let
s sãovar
s com escopo de bloco.const
s são imutáveis.%d
formata um número inteiro e%s
formata uma string. Eles são baseados em printf . Uma especificação está em andamento em console.spec.whatwg.org/#formatter .No ES6, é bom usar o loop for - of. Você pode obter um índice como este
Observe que
Array.entries()
retorna um iterador , que é o que permite que ele funcione no loop for-of; não confunda isso com Object.entries () , que retorna uma matriz de pares de valores-chave.fonte
entries()
é um objecto retornar vazio:{}
. Alguma idéia de por que isso seria? Myarray
é uma matriz de objetos.Object.entries(array)
vez dearray.entries()
next()
método que retornará entradas subsequentes na matriz toda vez que for chamado. Não há dados (visíveis) nele; você obtém os dados no objeto subjacente chamandonext()
, o que ocorre por trás dos bastidores. cc @tonygQue tal agora
Onde
array.forEach
este método possui umindex
parâmetro que é o índice do elemento atual sendo processado na matriz.fonte
break
não está disponível.Solução para pequenas coleções de matrizes:
arr - ARRAY, obj - CHAVE do elemento atual, i - COUNTER / INDEX
Aviso: Teclas de método () não estão disponíveis para a versão IE <9, você deve usar o código Polyfill . https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
fonte
var i = 0;
ei++;
é mais curto e mais eficiente. Além disso, ele não funciona para propriedades enumeráveis que não são propriedades próprias.Os loops de entrada iteram sobre as propriedades de um objeto. Não os use para matrizes, mesmo que elas funcionem algumas vezes.
As propriedades do objeto não têm índice, são todas iguais e não precisam ser executadas em uma ordem determinada. Se você quiser contar propriedades, precisará configurar o contador extra (como fez no seu primeiro exemplo).
loop sobre uma matriz:
loop sobre um objeto:
fonte
(var i=0; i<a.length; i++)
como é desperdiçado recursos. Use(var i=0, var len = a.length; i<len; i++)
var i=0; i<a.length; i++)
é o padrão de loop padrão que é otimizado por qualquer mecanismo javascript decente de qualquer maneira.var i=0; i<a.length; i++
é a melhor prática.Como outros já disseram, você não deve usar for..in para iterar sobre uma matriz.
Se você deseja uma sintaxe mais limpa, pode usar o forEach:
Se você deseja usar esse método, inclua o calço ES5 para adicionar suporte a navegadores mais antigos.
fonte
Resposta dada por rushUp Está correto, mas isso será mais conveniente
fonte
Aqui está uma função
eachWithIndex
que funciona com qualquer coisa iterável.Você também pode escrever uma função semelhante
eachWithKey
que funcione com objetos usandofor...in
.O bom dos geradores é que eles são preguiçosos e podem aceitar o resultado de outro gerador como argumento.
fonte
Essa é a minha versão de um iterador composto que gera um índice e o valor de qualquer função de gerador passada com um exemplo de pesquisa principal (lenta):
fonte
eachWithIndex[Symbol.iterator]
vez de apenas uma funçãoeachWithIndex
?eachWithIndex
não satisfaz a interface iterável, que é o ponto principalSymbol.iterator
.eachWithIndex
para aceitar iterável e retornar um composto fechado iterável.Além das respostas muito boas que todos postaram, quero acrescentar que a solução com melhor desempenho é o ES6
entries
. Parece contra- intuitivo para muitos desenvolvedores aqui, então eu criei esse perf benchamrk .É ~ 6 vezes mais rápido. Principalmente porque não precisa: a) acessar a matriz mais de uma vez e b) converter o índice.
fonte