¿Cómo puedo obtener una lista de valores únicos en una matriz? ¿Siempre tengo que usar una segunda matriz o hay algo similar al hashmap de java en JavaScript?
Voy a usar JavaScript y jQuery solamente. No se pueden usar bibliotecas adicionales.
javascript
jquery
Astronauta
fuente
fuente
underscore.js
biblioteca?list.toSet
Respuestas:
Como lo mencioné en los comentarios para la respuesta de @ Rocket, también puedo proporcionar un ejemplo que no use bibliotecas. Esto requiere dos nuevas funciones prototipo,
contains
yunique
Para mayor confiabilidad, puede reemplazar
contains
con laindexOf
cuña de MDN y verificar si cada elementoindexOf
es igual a -1: documentaciónfuente
~a.indexOf(b) === (a.indexOf(b) == -1)
if (~a.indexOf(b)) ...
es idéntico a escribir por más tiempoif (a.indexOf(b) == -1) ...
.O para aquellos que buscan un one-liner (simple y funcional), compatible con los navegadores actuales :
Actualización 18-04-2017
Parece que 'Array.prototype.includes' ahora tiene un amplio soporte en las últimas versiones de los navegadores principales ( compatibilidad )
Actualización 29-07-2015:
Hay planes en proceso para que los navegadores admitan un método estandarizado 'Array.prototype.includes', que aunque no responde directamente a esta pregunta; A menudo está relacionado.
Uso:
Pollyfill ( soporte de navegador , fuente de mozilla ):
fuente
Aquí hay una solución mucho más limpia para ES6 que veo que no está incluida aquí. Utiliza el conjunto y el operador de propagación :
...
Que vuelve
[1, 2]
fuente
Array.from(... new Set(a))
ya que Set no se puede convertir implícitamente a un tipo de matriz. Sólo un aviso!Array.from(new Set(a))
? Eso parece funcionar.One Liner, JavaScript puro
Con sintaxis ES6
list = list.filter((x, i, a) => a.indexOf(x) === i)
Con sintaxis ES5
Compatibilidad del navegador : IE9 +
fuente
a.indexOf(x) === i
nota de igualdad de los tres signos iguales.Usando EcmaScript 2016 simplemente puede hacerlo así.
Los conjuntos son siempre únicos y, al usarlos
Array.from()
, puede convertir un conjunto en una matriz. Como referencia, eche un vistazo a las documentaciones.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects /Conjunto
fuente
indexOf()
las respuestas son terribles porque son O (N ^ 2). Las respuestas extendidas están bien, pero no funcionarán para matrices grandes. Este es el mejor enfoque.Ahora en ES6 podemos usar la función ES6 recientemente introducida
O por la sintaxis de propagación de matriz en iterables
Devolverá el resultado único.
fuente
new Set
esta manera (como Angular / TypeScript moderno)let items = [1,1,1,1,3,4,5,2,23,1,4,4,4,2,2,2];
let uniqueItems = [...new Set(items)];
Si desea dejar la matriz original intacta,
necesita una segunda matriz para contener los elementos únicos de la primera
La mayoría de los navegadores tienen
Array.prototype.filter
:fuente
En estos días, puede usar el tipo de datos Set de ES6 para convertir su matriz en un Set único. Luego, si necesita usar métodos de matriz, puede convertirlo nuevamente en una matriz:
fuente
var uniqueArr = [...new Set(arr)]; // ["a", "b"]
No es nativo en Javascript, pero muchas bibliotecas tienen este método.
Underscore.js's
_.uniq(array)
( enlace ) funciona bastante bien ( fuente ).fuente
Usando jQuery, aquí hay una función única de Array que hice:
fuente
$.uniqueArray(arr)
? Incrustar referencias a jQuery dentroArray
del prototipo parece cuestionable$.uniqueArray
depende de jQuery; menos obvio queArray.prototype.unique
es así.prototype
s. Pero, entiendo tu punto ahora. Dejaré esto aquí de todos modos.Solución corta y dulce usando una segunda matriz;
fuente
¡Rápido, compacto, sin bucles anidados, funciona con cualquier objeto, no solo cadenas y números, toma un predicado y solo 5 líneas de código!
Ejemplo: para buscar elementos únicos por tipo:
Si desea que encuentre el primer elemento único en lugar del último, agregue una marca found.hasOwnPropery () allí.
fuente
Solo necesita Vanilla JS para encontrar elementos únicos con Array.some y Array.reduce. Con la sintaxis ES2015, solo tiene 62 caracteres.
Array.some y Array.reduce son compatibles con IE9 + y otros navegadores. Simplemente cambie las funciones de flecha gruesa para que las funciones regulares se admitan en navegadores que no admiten la sintaxis ES2015.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects / Array / Reducir
fuente
La mayoría de las soluciones anteriores tienen una alta complejidad de tiempo de ejecución.
Aquí está la solución que usa
reduce
y puede hacer el trabajo en O (n) tiempo.Nota:
Esta solución no depende de reducir. La idea es crear un mapa de objetos e insertar unos únicos en la matriz.
fuente
Manera ES6:
fuente
puedes usar,
te dará elementos únicos,
**> pero hay una trampa,
La segunda opción es utilizar el método de filtro en la matriz.
fuente
Puede ingresar una matriz con duplicados y el método siguiente devolverá la matriz con elementos únicos.
fuente
El único problema con las soluciones dadas hasta ahora es la eficiencia. Si le preocupa eso (y probablemente debería), debe evitar los bucles anidados: for * for, filter * indexOf, grep * inArray, todos iteran la matriz varias veces. Puede implementar un solo ciclo con soluciones como esta o esta
fuente
fuente
He intentado este problema en JS puro. He seguido los siguientes pasos 1. Ordene la matriz dada, 2. recorra la matriz ordenada, 3. Verifique el valor anterior y el valor siguiente con el valor actual
Manifestación
fuente
fuente
Teniendo en cuenta que
indexOf
devolverá la primera aparición de un elemento, puede hacer algo como esto:fuente
Si no necesita preocuparse tanto por los navegadores antiguos, esto es exactamente para lo que están diseñados los Conjuntos.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
fuente
Otro pensamiento de esta pregunta. Esto es lo que hice para lograr esto con menos código.
fuente
fuente
Aquí hay un enfoque con una
equals
función personalizable que puede usarse para primitivas y también para objetos personalizados:uso:
fuente
Mi respuesta utiliza
Array.filter
yArray.indexOf
métodos para obtener los valores únicosVi este enfoque en un sitio web pero su código es diferente de lo que parece aquí. He simplificado el código a una línea y lo he publicado aquí para que alguien se beneficie de él.
Nota: Mi enfoque es similar o igual al del trazador de líneas publicado por Josh. Lo dejo aquí ya que los nombres de las variables se explican por sí mismos en mi código.
fuente
Estaba pensando si podemos usar la búsqueda lineal para eliminar los duplicados:
}
HTML:
fuente
Aquí está la solución única al problema:
Copie y pegue esto en la consola del navegador y obtenga los resultados, yo :-)
fuente
He incorporado la función JQuery Unique .
Para obtener más información, puede consultar las Documentaciones de la API de jquery.
http://api.jquery.com/jquery.unique/
fuente