hand Inicio

Cómo eliminar duplicados de un array en JavaScript?

La manera más rápida, transformar el array en un Set y luego volver a un array

Multitud de veces necesitaremos eliminar duplicados de un array, y sorprendentemente no tenemos una función específica para eso

Pero no todo está perdido, vamos a ver las distintas estrategias que tenemos con las diferentes estructuras de datos

Arrays y Objects

En un array no tenemos problemas en almacenar duplicados

js
// definimos el array
const myArr = []
myArr[0] = '😎'
myArr[1] = '😎'
myArr[2] = '😎'

// lo mismo, pero de forma más concisa
const myArr = ['😎', '😎', '😎']

// lo mismo, más compacto si tuviésemos que definir 10 o 20 elementos
const myArr = Array.from({ length: 3 }, () => '😎')

Si en nuestros datos hay duplicados, un array los almacenará sin problemas

Esto, sin embargo, no pasa con un object

js
const myObj = { url: '😎', url: '😎', url: '😎' }
console.log(myObj) // {url: '😎'}

En este caso no hemos almacenado ningún duplicado, sólo una copia del mismo valor

Esto lo podemos aprovechar para eliminar duplicados de un array, aunque el código no es demasiado elegante

js
const myArr = ['😎', '😎', '😎', '😅'] // tenemos duplicados!

const newArr = []
const myObj = {}

myArr.forEach(el => {
// comprobamos si el valor existe en el objeto
if (!(el in myObj)) {
// si no existe creamos ese valor y lo añadimos al array final, y si sí existe no lo añadimos
myObj[el] = true
newArr.push(el)
}
})

console.log(myArr) // ["😎", "😎", "😎", "😅"]
console.log(newArr) // ["😎", "😅"]

Conseguido, hemos eliminado los duplicados, y en verdad podemos compactar más el código

js
const myArr = ['😎', '😎', '😎', '😅'] // tenemos duplicados!

const newArr = []
const myObj = {}
myArr.forEach(el => !(el in myObj) && (myObj[el] = true) && newArr.push(el))

console.log(myArr) // ["😎", "😎", "😎", "😅"]
console.log(newArr) // ["😎", "😅"]

Esta solución funciona, pero es ofuscada y algo complicada de leer la primera vez

Sets

Los sets son como los arrays pero con características de los object, y lo que nos interesa aquí es que NO pueden tener duplicados

js
const myArr = ['😎', '😎', '😎', '😅'] // tenemos duplicados!

const newArr = Array.from(new Set(myArr)) // con Array.from
const newArr2 = [...new Set(myArr)] // con el spread operator

console.log(myArr)
console.log(newArr)
console.log(newArr2)
/*
["😎", "😎", "😎", "😅"]
["😎", "😅"]
["😎", "😅"]
*/

Lo que hacemos es crear un array utilizando un set de intermediario, sirve perfectamente

Filter

Otra opción es "filtrar" el array y quedarnos sólo con elementos únicos, con la función filter()

js
const myArr = ['😎', '😎', '😎', '😅']
const newArr = myArr.filter((el, index) => myArr.indexOf(el) === index)

console.log(myArr)
console.log(newArr)

/*
["😎", "😎", "😎", "😅"]
["😎", "😅"]
*/

Es algo más ofuscado que el set de antes, pero no tanto como las primeras opciones

Con indexOf recuperamos el primer índice de ese elemento del array, es decir, tendremos para el array unos números de [0, 0, 0, 3]

Y con la comparación con indexOf(el) === index tendríamos [0 === 0, 0 === 1, 0 === 2, 3 === 3] con lo que sólo en el primer y último elemento recibiríamos un true y por lo tanto el filter devolvería sólo ese valor, eliminando por lo tanto los duplicados

Reduce

Y también tenemos el reduce, una función ofuscada por naturaleza pero increiblemente potente

js
const myArr = ['😎', '😎', '😎', '😅']
const newArr = myArr.reduce((newTempArr, el) => (newTempArr.includes(el) ? newTempArr : [...newTempArr, el]), [])

console.log(myArr)
console.log(newArr)

/*
["😎", "😎", "😎", "😅"]
["😎", "😅"]
*/

Con reduce empezamos con un array vacío y lo vamos llenando de valores siempre que no estén incluidos en el array original, lo que lo vemos con .includes()

Perfectamente válido, pero terrible para leer si no tienes acostumbrada la vista

draw of me

Hola, tienes en mente desarrollar una web?

Si quieres, te ayudo

Escríbeme