[1,2,3].forEach(function(el) {
if(el === 1) break;
});
Como posso fazer isso usando o novo forEach
método em JavaScript? Eu tentei return;
, return false;
e break
. break
trava e return
não faz nada além de continuar a iteração.
javascript
arrays
Scott Klarenbach
fonte
fonte
return
fato continue a iteração, pulará qualquer código que vier depois dele no bloco. Tome este código, por exemplo:[1,2,3].forEach(function(el) { if(el === 2) { console.log(`Match on 2!`); return; } console.log(el); });
.Oconsole.log(el);
será ignorado quando 2 corresponder.Respostas:
Não há como built-in capacidade de
break
nosforEach
. Para interromper a execução, você teria que lançar uma exceção de algum tipo. por exemplo.As exceções de JavaScript não são muito bonitas. Um
for
loop tradicional pode ser mais apropriado se você realmente precisarbreak
dele.Usar
Array#some
Em vez disso, use
Array#some
:Isso funciona porque
some
retornatrue
assim que qualquer retorno de chamada, executado em ordem de matriz, retornatrue
, causando um curto-circuito na execução do restante.some
, é inversoevery
(que será interrompido em areturn false
) eforEach
são todos os métodos do ECMAScript Fifth Edition que precisarão ser adicionados aosArray.prototype
navegadores nos quais estão ausentes.fonte
some
eevery
, isso deve estar no TOP na resposta. Não consigo entender por que as pessoas pensam que é menos legível. É simplesmente incrível!Array#some
é muito bom. Em primeiro lugar, é compatível com a maioria dos navegadores, incluindo ie9 e firefox 1.5, também funciona muito bem. Meu exemplo de caso de uso será encontrar o índice em uma matriz de intervalos [a, b] em que um número esteja entre um par de limite inferior e superior, testar e retornar true quando encontrado.for..of
seria a próxima melhor solução, embora apenas para navegadores mais recentes.Agora existe uma maneira ainda melhor de fazer isso no ECMAScript2015 (também conhecido como ES6) usando o novo loop for . Por exemplo, este código não imprime os elementos da matriz após o número 5:
Dos documentos:
Precisa do índice na iteração? Você pode usar
Array.entries()
:fonte
entries
. para (const [index, elemento] de someArray.entries ()) {// ...}Object.entries(myObject)
e usá-lo exatamente como você usafor..in
para o array. Observe que as matrizes JS são basicamente objetos ocultosVocê pode usar todos os métodos:
ES6
para suporte ao navegador antigo, use:
mais detalhes aqui .
fonte
[1,2,3].every( el => el !== 1 )
every
garante que as chamadas sejam feitas em sequência?k
inicia em 0 e é incrementado por 1: http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.everyCitando a partir da documentação MDN de
Array.prototype.forEach()
:Para o seu código (na pergunta), conforme sugerido por @bobince, use em seu
Array.prototype.some()
lugar. Serve muito bem para o seu caso.fonte
Infelizmente, neste caso, será muito melhor se você não usar
forEach
. Em vez disso, use umfor
loop regular e agora funcionará exatamente como você esperaria.fonte
Considere usar
jquery
oeach
método, pois permite retornar a função de retorno de chamada interna falsa:As bibliotecas Lodash também fornecem um
takeWhile
método que pode ser encadeado com map / reduce / fold etc:fonte
No seu exemplo de código, parece
Array.prototype.find
que você está procurando: Array.prototype.find () e Array.prototype.findIndex ()fonte
Se você quiser usar a sugestão de Dean Edward e lançar o erro StopIteration para interromper o loop sem precisar capturar o erro, use a seguinte função ( originalmente daqui ):
O código acima permitirá executar códigos como os seguintes, sem a necessidade de fazer suas próprias cláusulas try-catch:
Uma coisa importante a lembrar é que isso só atualizará a função Array.prototype.forEach se ela já existir. Se ainda não existir, não será modificado.
fonte
Resposta curta: use
for...break
para isso ou altere seu código para evitar a quebra deforEach
. Não use.some()
ou.every()
para emularfor...break
. Reescreva seu código para evitarfor...break
loop ou usefor...break
. Toda vez que você usa esses métodos comofor...break
alternativa, Deus mata um gatinho.Resposta longa:
.some()
e.every()
ambos retornamboolean
valor,.some()
retornamtrue
se houver algum elemento para o qual a função passada retornetrue
, todos retornarãofalse
se houver algum elemento para o qual a função passada retornefalse
. É isso que essas funções significam. Usar funções para o que elas não significam é muito pior do que usar tabelas para layout em vez de CSS, porque frustra todo mundo que lê seu código.Além disso, a única maneira possível de usar esses métodos como
for...break
alternativa é produzir efeitos colaterais (alterar alguns vars fora da.some()
função de retorno de chamada), e isso não é muito diferentefor...break
.Portanto, usar
.some()
ou.every()
comofor...break
alternativa de loop não está isento de efeitos colaterais, não é muito mais limpofor...break
, é frustrante, então não é melhor.Você sempre pode reescrever seu código para que não haja necessidade
for...break
. Você pode filtrar a matriz usando.filter()
, pode dividir a matriz usando.slice()
e assim por diante, depois usar.forEach()
ou.map()
para essa parte da matriz.fonte
for...break
loop se precisar de desempenho.for
laço é a ferramenta mais perfeita do que iteração.forEach()
,.any()
,.map()
,.filter()
etcIsso é apenas algo que eu criei para resolver o problema ... Tenho certeza de que corrige o problema que o solicitante original tinha:
E então você chamaria usando:
Retornar false dentro da função de retorno de chamada causará uma interrupção. Deixe-me saber se isso realmente não funciona.
fonte
=== false
pode ser melhor do que== false
isso, para que você não precise retornar explicitamente true (ou um valor verdadeiro) para continuar o loop, para que algum caminho de controle não retorne um valor e o loop quebre inesperadamente.Outro conceito que surgiu:
fonte
Array.prototype.forEach()
.for
ebreak
existia muito antes desta pergunta ser feita; o OP estava procurando esse comportamento usando, o mais funcionalforEach
,.for...in
ebreak
.fonte
Encontrei esta solução em outro site. Você pode agrupar o forEach em um cenário de tentativa / captura.
Mais detalhes aqui: http://dean.edwards.name/weblog/2006/07/enum/
fonte
Se você não precisar acessar sua matriz após a iteração, poderá resgatar definindo o comprimento da matriz como 0. Se ainda precisar dela após a iteração, poderá cloná-la usando a fatia.
Ou com um clone:
Qual é uma solução muito melhor do que lançar erros aleatórios no seu código.
fonte
array.length
a0
elas se aplicarão em iteração atual, então provavelmente às vezes é melhor usarreturn
depois de tal atribuiçãoEste é um loop for, mas mantém a referência do objeto no loop como um forEach (), mas você pode sair.
fonte
Como mencionado anteriormente, você não pode quebrar
.forEach()
.Aqui está uma maneira um pouco mais moderna de fazer um foreach com os Iteradores ES6. Permite que você obtenha acesso direto a
index
/value
durante a iteração.Resultado:
Ligações
Array.prototype.entries()
fonte
Ainda outra abordagem
fonte
Eu uso o nullhack para esse fim, ele tenta acessar a propriedade de
null
, que é um erro:fonte
throw BREAK
?Se você deseja manter sua
forEach
sintaxe, esta é uma maneira de mantê-la eficiente (embora não tão boa quanto um loop for normal). Verifique imediatamente se há uma variável que saiba se você deseja interromper o loop.Este exemplo usa uma função anônima para criar um escopo de função em torno do
forEach
qual você precisa armazenar as informações concluídas .Meus dois centavos.
fonte
Eu sei que não é o caminho certo. Não é quebrar o ciclo. É um Jugad
fonte
Use a
array.prototype.every
função, que fornece o utilitário para interromper o loop. Veja o exemplo aqui da documentação Javascript na rede de desenvolvedores Mozillafonte
Concordo com @bobince, votado.
Além disso, para sua informação:
O Prototype.js tem algo para esse fim:
$break
serão capturados e manipulados por Prototype.js internamente, interrompendo o ciclo "cada", mas sem gerar erros externos.Consulte API Prototype.JS para obter detalhes.
O jQuery também tem uma maneira, basta retornar false no manipulador para interromper o loop mais cedo:
Consulte a API do jQuery para obter detalhes.
fonte
Isso não é o mais eficiente, já que você ainda alterna todos os elementos, mas achei que poderia valer a pena considerar o muito simples:
fonte
continue
é uma palavra-chave, seu código é um erro de sintaxe.for of
loop e abreak;
partir disso, como de costume.você pode seguir o código abaixo, que funciona para mim:
fonte
Eu prefiro usar
for in
for in
funciona da mesma formaforEach
e você pode adicionar a função de retorno para sair dentro. Melhor desempenho também.fonte
Se você precisar quebrar com base no valor dos elementos que já estão em sua matriz, como no seu caso (ou seja, se a condição de interrupção não depender da variável em tempo de execução que pode mudar após a matriz receber seus valores de elemento), você também pode usar a combinação de fatia () e indexOf () seguinte maneira.
Se precisar interromper quando forEach chegar a 'Apple', você pode usar
Conforme declarado em W3Schools.com, o método slice () retorna os elementos selecionados em uma matriz, como um novo objeto de matriz. A matriz original não será alterada.
Veja no JSFiddle
Espero que ajude alguém.
fonte
Você pode criar uma variante
forEach
que permitebreak
,continue
,return
, e mesmoasync
/await
: (exemplo escrito à máquina)Uso:
fonte
tente com "encontrar":
fonte
Sim, é possível continuar e sair de um loop forEach.
Para continuar, você pode usar return, o loop continuará, mas a função atual terminará.
Para sair do loop, você pode definir o terceiro parâmetro como comprimento 0, definido como matriz vazia. O loop não continua, a função atual continua, então você pode usar "return" para finalizar, como sair de um loop normal para ...
Este:
imprimirá isto:
fonte
Antes, meu código está abaixo
Eu mudei para abaixo, foi corrigido.
fonte