Luego de mirar en varios repositorios y páginas al terminar dimos con la solución que te mostramos a continuación.
Solución:
Con JavaScript 1.6 / ECMAScript 5 puedes usar el nativo filter
método de un Array de la siguiente manera para obtener un array con valores únicos:
function onlyUnique(value, index, self)
return self.indexOf(value) === index;
// usage example:
var a = ['a', 1, 'a', 2, '1'];
var unique = a.filter(onlyUnique);
console.log(unique); // ['a', 1, 2, '1']
El método nativo filter
recorrerá el array y deje solo aquellas entradas que pasan la función de devolución de llamada dada onlyUnique
.
onlyUnique
comprueba si el valor dado es el primero que se produce. De lo contrario, debe ser un duplicado y no se copiará.
Esta solución funciona sin ninguna biblioteca adicional como jQuery o prototipo.js.
Funciona para arreglos con mixed tipos de valor también.
Para navegadores antiguos ( filter
y indexOf
puede encontrar soluciones alternativas en la documentación de MDN para filter e indexOf.
Si desea mantener la última aparición de un valor, simplemente reemplace indexOf
por lastIndexOf
.
Con ES6 podría acortarse a esto:
// usage example:
var myArray = ['a', 1, 'a', 2, '1'];
var unique = myArray.filter((v, i, a) => a.indexOf(v) === i);
console.log(unique); // unique is ['a', 1, 2, '1']
Gracias a Camilo Martin por la pista en el comentario.
ES6 tiene un objeto nativo Set
para almacenar valores únicos. para obtener un array con valores únicos podrías hacer ahora esto:
var myArray = ['a', 1, 'a', 2, '1'];
let unique = [...new Set(myArray)];
console.log(unique); // unique is ['a', 1, 2, '1']
el constructor de Set
toma un objeto iterable, como Array, y el operador de propagación ...
transformar el conjunto de nuevo en una matriz. Gracias a Lukas Liese por la pista en el comentario.
Respuesta actualizada para ES6/ES2015: Usando el operador Set y spread (gracias le-m), la solución de una sola línea es:
let uniqueItems = [...new Set(items)]
que vuelve
[4, 5, 6, 3, 2, 23, 1]
Divido todas las respuestas a 4 posibles soluciones:
- Usar objeto
- usar ayudante array
[ ]
- Utilizar
filter + indexOf
- ¡Prima! ES6
Sets
método.
Aquí hay ejemplos de códigos encontrados en las respuestas:
Usar objeto
para evitar duplicados
function uniqueArray1( ar )
var j = ;
ar.forEach( function(v)
j[v+ '::' + typeof v] = v;
);
return Object.keys(j).map(function(v)
return j[v];
);
usar ayudante array [ ]
function uniqueArray2(arr)
var a = [];
for (var i=0, l=arr.length; i
Utilizar filter + indexOf
function uniqueArray3(a)
function onlyUnique(value, index, self)
return self.indexOf(value) === index;
// usage
var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1']
return unique;
Utilizar ES6[...new Set(a)]
function uniqueArray4(a)
return [...new Set(a)];
Y me preguntaba cuál es más rápido. Hice una muestra de Google Sheet para probar funciones. Nota: ECMA 6 no está disponible en Hojas de cálculo de Google, por lo que no puedo probarlo.
Aquí está el resultado de las pruebas:
Esperaba ver ese código usando objeto
ganará porque usa hash. Así que me alegro de que las pruebas hayan mostrado los mejores resultados para este algoritmo en Chrome e IE. Gracias a @rab por el código.
Actualización 2020
Motor ES6 habilitado para Google Script. Ahora probé el último código con Sets
y apareció más rápido que el método del objeto.
valoraciones y reseñas
Al final de todo puedes encontrar las explicaciones de otros usuarios, tú además puedes insertar el tuyo si te apetece.