Tengo una matriz de destino ["apple","banana","orange"]
y quiero verificar si otras matrices contienen alguno de los elementos de la matriz de destino.
Por ejemplo:
["apple","grape"] //returns true;
["apple","banana","pineapple"] //returns true;
["grape", "pineapple"] //returns false;
¿Cómo puedo hacerlo en JavaScript?
javascript
arrays
Alex
fuente
fuente
for
bucle e itere sobre la matriz de destino. Si cada elemento está contenido dentro de la matriz actual (usocurrent.indexOf(elem) !== -1)
, entonces están todos allí.Respuestas:
Vanilla JS
ES2016:
ES6:
Cómo funciona
some(..)
comprueba cada elemento de la matriz con una función de prueba y devuelve verdadero si algún elemento de la matriz pasa la función de prueba, de lo contrario, devuelve falso.indexOf(..) >= 0
yincludes(..)
ambos devuelven verdadero si el argumento dado está presente en la matriz.fuente
true
si algún elemento de la matriz pasa la función de prueba. De lo contrario, vuelvefalse
.[false, false, false]
lugar de una matriz vacía[]
?vainilla js
fuente
some()
es rad. Se cierra tan pronto como algo coincide.arr.some(v=> haystack.indexOf(v) >= 0)
arr.some(v => haystack.includes(v))
arr1.some(v => arr2.indexOf(v) >= 0)
.includes
, ya que aparentemente no es compatible con IE: stackoverflow.com/questions/36574351/…Si no se opone a usar una biblioteca, http://underscorejs.org/ tiene un método de intersección, que puede simplificar esto:
La función de intersección devolverá una nueva matriz con los elementos con los que coincide y, si no coincide, devuelve una matriz vacía.
fuente
ES6 (el más rápido)
ES2016
Guion bajo
DEMO: https://jsfiddle.net/r257wuv5/
jsPerf: https://jsperf.com/array-contains-any-element-of-another-array
fuente
Si no necesita la coerción de tipo (debido al uso de
indexOf
), puede intentar algo como lo siguiente:Donde
arr
contiene los elementos de destino. Al final,found
se mostrará si la segunda matriz tenía al menos una coincidencia contra el objetivo.Por supuesto, puede intercambiar números por cualquier cosa que desee usar: las cadenas están bien, como su ejemplo.
Y en mi ejemplo específico, el resultado debería ser
true
porque la segunda matriz3
existe en el objetivo.ACTUALIZAR:
Así es como lo organizaría en una función (con algunos cambios menores de antes):
DEMO: http://jsfiddle.net/u8Bzt/
En este caso, la función podría modificarse para
targetArray
pasarla como argumento en lugar de codificarse en el cierre.ACTUALIZACIÓN2:
Si bien mi solución anterior puede funcionar y ser (con suerte más) legible, creo que la "mejor" forma de manejar el concepto que describí es hacer algo un poco diferente. El "problema" con la solución anterior es que el
indexOf
interior del bucle hace que la matriz de destino se repita completamente para cada elemento de la otra matriz. Esto se puede "arreglar" fácilmente mediante el uso de una "búsqueda" (un mapa ... un literal de objeto JavaScript). Esto permite dos bucles simples, sobre cada matriz. Aquí hay un ejemplo:DEMO: http://jsfiddle.net/5Lv9v/
La desventaja de esta solución es que solo se pueden usar (correctamente) números y cadenas (y booleanos), porque los valores se convierten (implícitamente) en cadenas y se establecen como las claves del mapa de búsqueda. Esto no es exactamente bueno / posible / fácil de hacer para valores no literales.
fuente
undefined
... para eso!!
está", eso está mal. Devolverá la oposición booleana de!
.Solución ES6:
A diferencia de esto: debe contener todos los valores.
Espero, será de ayuda.
fuente
Podrías usar lodash y hacer:
Establecer intersección se realiza en ambas colecciones produciendo una matriz de elementos idénticos.
fuente
intersection
que seguirá comparando incluso después de encontrar la primera coincidencia para encontrarlos a todos. Es como usarfilter
cuando solo necesitasfind
.Usando filter / indexOf :
fuente
O incluso puede tener un mejor rendimiento si primero descubre cuál de estas dos matrices es más larga y
Set
busca la matriz más larga, mientras aplica elsome
método en la más corta:fuente
indexOf
yincludes
, usted es el primero en responder con la solución basada en conjuntos más eficiente, utilizando el nativoSet
, 4 años después de que se introdujo en EcmaScript. +1Encontré esta sintaxis corta y dulce para que coincida con todos o algunos elementos entre dos matrices. Por ejemplo
// operación OR. encuentre si alguno de los elementos de array2 existe en array1. Esto volverá tan pronto como haya una primera coincidencia ya que algunos métodos se rompen cuando la función devuelve VERDADERO
// imprime VERDADERO
// Y operación. encuentre si todos los elementos de array2 existen en array1. Esto volverá tan pronto como no haya una primera coincidencia ya que algunos métodos se rompen cuando la función devuelve VERDADERO
// imprime FALSO
Espero que ayude a alguien en el futuro!
fuente
Puede usar una llamada anidada Array.prototype.some. Esto tiene el beneficio de que se rescatará en la primera coincidencia en lugar de otras soluciones que se ejecutarán a través del bucle anidado completo.
p.ej.
fuente
Aquí hay un caso interesante que pensé que debería compartir.
Digamos que tiene una matriz de objetos y una matriz de filtros seleccionados.
Para aplicar los filtros seleccionados a esta estructura podemos
fuente
Escribí 3 soluciones. Esencialmente hacen lo mismo. Vuelven verdad tan pronto como llegan
true
. Escribí las 3 soluciones solo para mostrar 3 formas diferentes de hacer las cosas. Ahora, depende de lo que más te guste. Puedes usar performance.now () para verificar el rendimiento de una solución u otra. En mis soluciones también estoy verificando qué matriz es la más grande y cuál es la más pequeña para que las operaciones sean más eficientes.La tercera solución puede no ser la más linda pero es eficiente. Decidí agregarlo porque en algunas entrevistas de codificación no está permitido usar métodos integrados.
Por último, claro ... podemos llegar a una solución con 2 NESTED para bucles (la forma de fuerza bruta) pero desea evitar eso porque la complejidad del tiempo es mala O (n ^ 2) .
Nota:
indexOf () vs incluye ()
¿Cuál tiene mejor rendimiento ?
indexOf()
por un momento, pero incluye es más legible en mi opinión.Si no me equivoco
.includes()
yindexOf()
uso bucles detrás de la escena, entonces estarás en O (n ^ 2) cuando los uses.some()
.USANDO bucle
USANDO .some ()
USO DE MAPAS Complejidad de tiempo O (2n) => O (n)
Código en mi: stackblitz
No soy un experto en rendimiento ni BigO, así que si algo que dije está mal, hágamelo saber.
fuente
¿Qué pasa con el uso de una combinación de algunos / findIndex e indexOf?
Entonces algo como esto:
Para hacerlo más legible, puede agregar esta funcionalidad al objeto Array en sí.
Nota: Si desea hacer algo con un predicado, puede reemplazar el indexOf interno con otro findIndex y un predicado
fuente
Mi solución aplica Array.prototype.some () y Array.prototype.includes () ayudantes de matriz que también hacen su trabajo bastante eficiente
ES6
fuente
Solo una solución más
Compruebe si a1 contiene todos los elementos de a2
fuente
Se puede hacer simplemente iterando a través de la matriz principal y verifica si otra matriz contiene o no el elemento objetivo.
Prueba esto:
DEMO en JSFIDDLE
fuente
Con guiones bajos
fuente
indexOf
, creo que es lo contrario :). Por otro lado, estoy de acuerdo en tratar de no agregar bibliotecas externas si realmente no son necesarias, pero no estoy realmente obsesionado con eso, las bibliotecas de terceros no solo ofrecen funcionalidades útiles sino también funcionalidades sólidas . Por ejemplo: ¿ha probado todos los casos límite y navegadores principales con su solución? ... (por cierto,every
no está tratando de encontrar un índice en una lista sino evaluando algo en cada elemento de la lista)Agregar al prototipo de matriz
Descargo de responsabilidad: muchos aconsejarían en contra de esto La única vez que realmente sería un problema era si una biblioteca agregaba una función prototipo con el mismo nombre (que se comportaba de manera diferente) o algo así.
Código:
Sin usar las funciones de flecha grande:
Uso
fuente
Vanilla JS con coincidencia parcial e insensible
El problema con algunos enfoques anteriores es que requieren una coincidencia exacta de cada palabra . Pero, ¿qué sucede si desea proporcionar resultados para coincidencias parciales?
Esto es útil cuando desea proporcionar un cuadro de búsqueda donde los usuarios escriben palabras y los resultados pueden tener esas palabras en cualquier orden, posición y caso.
fuente
Actualice la respuesta de @Paul Grimshaw, use
includes
insteed ofindexOf
para leer másfuente
Se me ocurrió una solución en el nodo usando subrayado js como este:
fuente
Personalmente, usaría la siguiente función:
El método "toString ()" siempre usará comas para separar los valores. Solo funcionará realmente con tipos primitivos.
fuente
La matriz .filter () con una llamada anidada a .find () devolverá todos los elementos de la primera matriz que son miembros de la segunda matriz. Verifique la longitud de la matriz devuelta para determinar si alguna de la segunda matriz estaba en la primera matriz.
fuente
fuente
fuente