Gostaria de saber se existe uma maneira conhecida, embutida / elegante de encontrar o primeiro elemento de uma matriz JS que corresponda a uma determinada condição. AC # equivalente seria List.Find .
Até agora, eu tenho usado uma combinação de duas funções como esta:
// Returns the first element of an array that satisfies given predicate
Array.prototype.findFirst = function (predicateCallback) {
if (typeof predicateCallback !== 'function') {
return undefined;
}
for (var i = 0; i < arr.length; i++) {
if (i in this && predicateCallback(this[i])) return this[i];
}
return undefined;
};
// Check if element is not undefined && not null
isNotNullNorUndefined = function (o) {
return (typeof (o) !== 'undefined' && o !== null);
};
E então eu posso usar:
var result = someArray.findFirst(isNotNullNorUndefined);
Mas como existem muitos métodos de matriz de estilo funcional no ECMAScript , talvez já exista algo como esse? Eu imagino que muitas pessoas precisam implementar coisas assim o tempo todo ...
javascript
arrays
Jakub P.
fonte
fonte
return (typeof (o) !== 'undefined' && o !== null);
até issoreturn o != null;
. Eles são exatamente equivalentes.Respostas:
Desde o ES6, existe o
find
método nativo para matrizes; isso para de enumerar a matriz depois de encontrar a primeira correspondência e retornar o valor.Resposta antiga:
Tenho que postar uma resposta para interromper essas
filter
sugestões :-)Você pode usar o
some
método Array para iterar a matriz até que uma condição seja atendida (e depois pare). Infelizmente, ele retornará apenas se a condição foi atendida uma vez, não por qual elemento (ou em qual índice) foi atendida. Então, temos que corrigi-lo um pouco:fonte
some()
por outro lado, retorna imediatamente, o que é muito mais rápido em quase todos os casos do que as soluções de filtragem.A partir do ECMAScript 6, você pode usar
Array.prototype.find
para isso. Isso é implementado e funciona no Firefox (25.0), Chrome (45.0), Edge (12) e Safari (7.1), mas não no Internet Explorer ou em várias outras plataformas antigas ou incomuns .Por exemplo, a expressão abaixo é avaliada como
106
.Se você quiser usar isso agora, mas precisar de suporte para o IE ou outros navegadores não compatíveis, use um calço. Eu recomendo o es6-shim . O MDN também oferece um calço se, por algum motivo, você não quiser colocar todo o es6-shim em seu projeto. Para obter compatibilidade máxima, você deseja o es6-shim, porque, ao contrário da versão MDN, ele detecta implementações nativas de bugs
find
e as substitui (consulte o comentário que começa em "Como solucionar bugs na matriz # find e Array # findIndex" e nas linhas imediatamente a seguir) .fonte
find
é melhor do quefilter
desde quefind
para imediatamente quando encontra um elemento correspondente à condição, enquantofilter
percorre todos os elementos para fornecer todos os elementos correspondentes.Que tal usar filtro e obter o primeiro índice da matriz resultante?
fonte
.shift
aqui?shift
é que "parece inteligente", mas na verdade é mais confuso. Quem pensaria que chamarshift()
sem argumentos seria o mesmo que pegar o primeiro elemento? Não está claro IMO. De qualquer forma, o acesso à matriz é mais rápido: jsperf.com/array-access-vs-shift.shift()
sobre[0]
explicitamente declarada dessa maneira. Apesar disso, é uma alternativa que você pode optar por usar ou não[0]
.Já deve estar claro que o JavaScript não oferece essa solução nativamente; Aqui estão as duas derivadas mais próximas, as mais úteis primeiro:
Array.prototype.some(fn)
oferece o comportamento desejado de parar quando uma condição é atendida, mas retorna apenas se um elemento está presente; não é difícil aplicar alguns truques, como a solução oferecida pela resposta de Bergi .Array.prototype.filter(fn)[0]
cria um ótimo one-liner, mas é o menos eficiente, porque você joga fora osN - 1
elementos apenas para conseguir o que precisa.Os métodos de pesquisa tradicionais em JavaScript são caracterizados pelo retorno do índice do elemento encontrado em vez do próprio elemento ou -1. Isso evita ter que escolher um valor de retorno do domínio de todos os tipos possíveis; um índice pode ser apenas um número e valores negativos são inválidos.
As duas soluções acima também não oferecem suporte à pesquisa de deslocamento, então decidi escrever o seguinte:
fonte
Resumo:
ES6
find()
find()
está localizadoArray.prototype
para que possa ser usado em todas as matrizes.find()
recebe um retorno de chamada onde umaboolean
condição é testada. A função retorna o valor (não o índice!)Exemplo:
fonte
Se você estiver usando,
underscore.js
poderá usar as funçõesfind
eindexOf
para obter exatamente o que deseja:Documentação:
fonte
A partir do ES 2015,
Array.prototype.find()
fornece essa funcionalidade exata.Para navegadores que não suportam esse recurso, a Mozilla Developer Network forneceu um polyfill (colado abaixo):
fonte
Array.prototype.find () faz exatamente isso, mais informações: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
fonte
fonte
Eu me inspirei em várias fontes na internet para derivar a solução abaixo. Queria levar em consideração algum valor padrão e fornecer uma maneira de comparar cada entrada para uma abordagem genérica que isso resolve.
Uso: (dando valor "Segundo")
Implementação:
fonte
Não há função interna no Javascript para realizar esta pesquisa.
Se você estiver usando o jQuery, poderá fazer a
jQuery.inArray(element,array)
.fonte
$.inArray
não retorna um booleano; ele (surpreendentemente!) Retorna o índice do primeiro elemento correspondente. Ainda não faz o que o OP pediu, no entanto.Uma maneira menos elegante que exibirá
throw
todas as mensagens de erro corretas (com base emArray.prototype.filter
), mas interromperá a iteração no primeiro resultado éEntão exemplos são
Funciona terminando
filter
usandothrow
.fonte