Eu tenho uma matriz de destino ["apple","banana","orange"]
e quero verificar se outras matrizes contêm algum dos elementos da matriz de destino.
Por exemplo:
["apple","grape"] //returns true;
["apple","banana","pineapple"] //returns true;
["grape", "pineapple"] //returns false;
Como posso fazer isso em JavaScript?
javascript
arrays
Alex
fonte
fonte
for
loop e itere sobre a matriz de destino. Se cada elemento está contido dentro da matriz atual (usocurrent.indexOf(elem) !== -1)
, em seguida, eles estão todos lá.Respostas:
JS de baunilha
ES2016:
ES6:
Como funciona
some(..)
verifica cada elemento da matriz em relação a uma função de teste e retorna true se algum elemento da matriz passa na função de teste, caso contrário, ele retorna false.indexOf(..) >= 0
eincludes(..)
ambos retornam true se o argumento fornecido estiver presente na matriz.fonte
true
se algum elemento da matriz passa na função de teste. Caso contrário, ele retornaráfalse
.[false, false, false]
vez de uma matriz vazia[]
?js de baunilha
fonte
some()
é rad. Sai assim que algo coincide.arr.some(v=> haystack.indexOf(v) >= 0)
arr.some(v => haystack.includes(v))
arr1.some(v => arr2.indexOf(v) >= 0)
.includes
, como aparentemente não é suportado no IE: stackoverflow.com/questions/36574351/...Se você não se opõe a usar uma biblioteca, http://underscorejs.org/ possui um método de interseção, que pode simplificar isso:
A função de interseção retornará uma nova matriz com os itens correspondentes e, se não corresponder, retornará uma matriz vazia.
fonte
ES6 (mais rápido)
ES2016
Sublinhado
DEMO: https://jsfiddle.net/r257wuv5/
jsPerf: https://jsperf.com/array-contains-any-element-of-another-array
fonte
Se você não precisar de coerção de tipo (por causa do uso de
indexOf
), tente algo como o seguinte:Onde
arr
contém os itens de destino. No final,found
mostrará se a segunda matriz teve pelo menos uma partida contra o alvo.Claro, você pode trocar números por qualquer coisa que queira usar - as strings são boas, como no seu exemplo.
E no meu exemplo específico, o resultado deve ser
true
porque a segunda matriz3
existe no destino.ATUALIZAR:
Aqui está como eu organizaria isso em uma função (com algumas pequenas alterações de antes):
DEMO: http://jsfiddle.net/u8Bzt/
Nesse caso, a função pode ser modificada para
targetArray
ser passada como argumento em vez de codificada no fechamento.UPDATE2:
Embora minha solução acima possa funcionar e ser (espero que mais) legível, acredito que a maneira "melhor" de lidar com o conceito que descrevi é fazer algo um pouco diferente. O "problema" com a solução acima é que o
indexOf
interior do loop faz com que o array de destino seja repetido completamente para cada item do outro array. Isso pode ser facilmente "consertado" usando uma "pesquisa" (um mapa ... um literal de objeto JavaScript). Isso permite dois loops simples, sobre cada matriz. Aqui está um exemplo:DEMO: http://jsfiddle.net/5Lv9v/
A desvantagem desta solução é que apenas números e cadeias (e booleanos) podem ser usados (corretamente), porque os valores são (implicitamente) convertidos em cadeias e configurados como as chaves do mapa de pesquisa. Isso não é exatamente bom / possível / fácil para valores não literais.
fonte
undefined
...!!
é para isso que serve" - isso está errado. Retornará a oposição booleana de!
.Solução ES6:
Ao contrário: Must contém todos os valores.
Espero que seja útil.
fonte
Você pode usar o lodash e fazer:
A interseção do conjunto é feita nas duas coleções, produzindo uma matriz de elementos idênticos.
fonte
intersection
continua comparando mesmo depois de encontrar a primeira correspondência para encontrar todas elas. É como usarfilter
quando você precisafind
.Usando filter / indexOf :
fonte
Ou você pode até ter um desempenho melhor se descobrir primeiro qual dessas duas matrizes é mais longa e compensar
Set
a matriz mais longa, enquanto aplica osome
método na menor:fonte
indexOf
eincludes
, você é o primeiro a responder com a solução baseada em conjunto mais eficiente, usando a nativaSet
, quatro anos depois de ter sido introduzida no EcmaScript. +1Eu achei essa sintaxe curta e agradável para combinar todos ou alguns elementos entre duas matrizes. Por exemplo
// operação OR. encontre se algum dos elementos da matriz2 existe na matriz1. Isso retornará assim que houver uma primeira correspondência, pois algum método será interrompido quando a função retornar TRUE
// imprime TRUE
// operação AND. encontre se todos os elementos do array2 existem no array1. Isso retornará assim que não houver uma primeira correspondência, pois algum método será interrompido quando a função retornar TRUE
// imprime FALSE
Espero que ajude alguém no futuro!
fonte
Você pode usar uma chamada Array.prototype.some aninhada. Isso tem o benefício de ser resgatado na primeira partida, em vez de outras soluções que serão executadas no loop aninhado completo.
por exemplo.
fonte
Aqui está um caso interessante que pensei que deveria compartilhar.
Digamos que você tenha uma matriz de objetos e uma matriz de filtros selecionados.
Para aplicar os filtros selecionados a essa estrutura, podemos
fonte
Eu escrevi 3 soluções. Essencialmente, eles fazem o mesmo. Eles retornam verdadeiros assim que são alcançados
true
. Eu escrevi as 3 soluções apenas para mostrar três maneiras diferentes de fazer as coisas. Agora, depende do que você mais gosta. Você pode usar o performance.now () para verificar o desempenho de uma solução ou de outra. Nas minhas soluções, também estou verificando qual matriz é a maior e qual é a menor para tornar as operações mais eficientes.A terceira solução pode não ser a mais fofa, mas é eficiente. Decidi adicioná-lo porque em algumas entrevistas de codificação você não tem permissão para usar métodos internos.
Por fim, claro ... podemos encontrar uma solução com 2 NESTED para loops (a maneira da força bruta), mas você deseja evitar isso porque a complexidade do tempo é ruim O (n ^ 2) .
Nota:
indexOf () vs includes ()
Qual deles tem melhor desempenho ?
indexOf()
por um pouco, mas inclui é mais legível na minha opinião.Se não me engano
.includes()
eindexOf()
usar loops nos bastidores, você estará em O (n ^ 2) ao usá-los.some()
.Loop USING
USANDO .some ()
UTILIZAÇÃO DE MAPAS Complexidade temporal O (2n) => O (n)
Código no meu: stackblitz
Eu não sou especialista em desempenho nem em BigO; se algo que eu disse estiver errado, me avise.
fonte
Que tal usar uma combinação de some / findIndex e indexOf?
Então, algo como isto:
Para torná-lo mais legível, você pode adicionar essa funcionalidade ao próprio objeto Array.
Nota: Se você quiser fazer algo com um predicado, poderá substituir o indexOf interno por outro findIndex e um predicado
fonte
Minha solução aplica Array.prototype.some () e Array.prototype.includes () ajudantes de matriz que também fazem seu trabalho de maneira bastante eficiente
ES6
fonte
Apenas mais uma solução
Verifique se a1 contém todo o elemento de a2
fonte
Isso pode ser feito através da iteração na matriz principal e verifique se outra matriz contém algum elemento de destino ou não.
Tente o seguinte:
DEMO na JSFIDDLE
fonte
With underscorejs
fonte
indexOf
, acho que é o contrário :). Por outro lado, concordo em tentar não adicionar bibliotecas externas se elas não forem realmente necessárias, mas não sou muito obsessivo com isso, as bibliotecas de terceiros não apenas oferecem funcionalidades úteis, mas também funcionalidades sólidas . Por exemplo: você já testou todos os casos extremos e os principais navegadores com sua solução? .. (a propósito,every
não está tentando encontrar um índice em uma lista, mas avaliando algo em todos os elementos da lista)Adicionando ao protótipo de matriz
Aviso Legal: Muitos aconselham fortemente contra isso. A única vez que realmente seria um problema era se uma biblioteca adicionasse uma função de protótipo com o mesmo nome (que se comportasse de maneira diferente) ou algo assim.
Código:
Sem usar funções de seta grande:
Uso
fonte
JS de baunilha com correspondência parcial e sem distinção entre maiúsculas e minúsculas
O problema com algumas abordagens anteriores é que elas exigem uma correspondência exata de cada palavra . Mas, e se você quiser fornecer resultados para correspondências parciais?
Isso é útil quando você deseja fornecer uma caixa de pesquisa na qual os usuários digitam palavras e os resultados podem ter essas palavras em qualquer ordem, posição e caso.
fonte
Atualize a resposta do @Paul Grimshaw, use o
includes
insteed deindexOf
para mais legibilidadefonte
Eu vim com uma solução no nó usando sublinhado js como este:
fonte
Pessoalmente, eu usaria a seguinte função:
O método "toString ()" sempre usará vírgulas para separar os valores. Realmente só funcionará com tipos primitivos.
fonte
Matriz .filter () com uma chamada aninhada para .find () retornará todos os elementos na primeira matriz que são membros da segunda matriz. Verifique o comprimento da matriz retornada para determinar se alguma da segunda matriz estava na primeira matriz.
fonte
fonte
fonte