馃枛 Inicio

SERVICIOS

Salir

noched铆a

C贸mo eliminar duplicados de un array en JavaScript?

500 palabras
2 minutos
April 20, 2020
blogjavascript

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

  1. Pr贸logo
  2. Arrays
  3. Sets
  4. Filter
  5. Reduce
  6. Resumen

Pr贸logo

Multitud de veces necesitaremos eliminar duplicados de un array y aunque pueda parecer lo contrario, no tenemos una funci贸n que nos lo haga de serie

Arrays

En un array no tenemos problemas en almacenar duplicados

js
const myArr = []
myArr[0] = '馃槑'
myArr[1] = '馃槑'
myArr[2] = '馃槑'
// m谩s conciso
const myArr = ['馃槑', '馃槑', '馃槑']
// m谩s compacto
const myArr = Array.from({ length: 3 }, () => '馃槑')

Algo que por ejemplo no podr铆amos hacer con un object, o s铆, pero s贸lo nos almacenar谩 el 煤ltimo valor (ir谩 sobreescribiendo)

js
const myObj = { url: '馃槑', url: '馃槑', url: '馃槑' }
// {url: '馃槑'}

De hecho, podemos aprovechar que los objetos no pueden tener valores duplicados para eliminar los duplicados de un array, aunque el c贸digo sale algo ofuscado

js
const myArr = ['馃槑', '馃槑', '馃槑', '馃槄'] // queremos quedarnos con ['馃槑', '馃槄']
const newArr = []
const myObj = []
myArr.forEach(el => {
if (!(el in myObj)) {
myObj[el] = true
newArr.push(el)
}
})
console.log(myArr)
console.log(newArr)
// m谩s compacto
myArr.forEach(el => !(el in myObj) && (myObj[el] = true) && newArr.push(el))
/*
["馃槑", "馃槑", "馃槑", "馃槄"]
["馃槑", "馃槄"]
*/

El c贸digo simplemente

  • Itera sobre el array
  • A帽ade el elemento del array como elemento en el objeto (con key el elemento y con value el true)
  • A帽ade el elemento en un array nuevo
  • Pero si el elemento ya existe en el objeto, no hace ni lo uno ni lo otro

Sets

Con los sets tenemos una especie de h铆brido entre un objeto y un array, que para lo que nos importa se trata de un array que no puede tener duplicados

Entonces?

Por qu茅 no olvidarse de los arrays y utilizar s贸lo sets?

Sin duda ser铆a una opci贸n, pero encuentro el uso del array bastante (bastate) m谩s c贸modo, y perdemos cosas (como no poder utilizar la funci贸n .map())

Conclusi贸n, puedes odiar los set, pero para eliminar duplicados de un array representa la mejor opci贸n de todas

js
const myArr = ['馃槑', '馃槑', '馃槑', '馃槄']
const newArr = Array.from(new Set(myArr))
// o tambi茅n utilizando otra nomenclatura (totalmente equivalente)
const newArr2 = [...new Set(myArr)]
console.log(myArr)
console.log(newArr)
console.log(newArr2)
/*
["馃槑", "馃槑", "馃槑", "馃槄"]
["馃槑", "馃槄"]
["馃槑", "馃槄"]
*/

Qu茅 utilizar, el `Array.from' o el 'spread operator' (los 3 puntitos)? Va a gustos, pero el spread operator permite escribir menos, algo que siempre se agradece (y mucho)

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)
/*
["馃槑", "馃槑", "馃槑", "馃槄"]
["馃槑", "馃槄"]
*/

Resulta m谩s complicado de leer (sin duda!)

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 el valor

Es elegante, no dir茅 que no, pero mucho menos directa que la soluci贸n anterior

Reduce

Y para terminar, siempre tenemos el reduce, una funci贸n ofuscada por naturaleza pero increiblemente potente (parece que para todos los problemas siempre hay una soluci贸n basada en reduce)

En una l铆nea (que no es suficiente para domesticar el reduce), lo que hace esa funci贸n es ir recorriendo el array pero recibiendo en cada iteraci贸n el elemento anterior

Claro como el agua 馃槓

js
const myArr = ['馃槑', '馃槑', '馃槑', '馃槄']
const newArr = myArr.reduce((newTempArr, el) => (newTempArr.includes(el) ? newTempArr : [...newTempArr, el]), [])
console.log(myArr)
console.log(newArr)
/*
["馃槑", "馃槑", "馃槑", "馃槄"]
["馃槑", "馃槄"]
*/

B谩sicamente, reduce nos manda el elemento anterior, pero qu茅 es el elemento anterior?

Pues el elemento anterior del array 馃槓

Y cuando empiezas, cu谩l es ese elemento anterior, si no existe?

Pues lo indicamos con reduce(mifuncion, []), es decir, que como segundo argumento pasamos ese valor inicial que recibiremos

Y d贸nde lo recibiremos?

Pues en la funci贸n, como argumento (mifuncion arriba, aunque lo suyo es poner directamente una funci贸n al estilo () => {...})

Esa funci贸n recibe dos argumentos (elementoAnterior, elemento) => {}

Y con esos dos argumentos miramos si el elemento anterior ya tiene el elemento nuevo elementoAnterior.includes(elemento) ?

Si es el caso, devolvemos el mismo array elementoAnterior

Si no es el caso, le a帽adimos el elemento al nuevo array, que lo podr铆amos hacer con un push() o con un Array.from o de este modo, con el spread operator

Simplemente [...elementoAnterior, elemento]

Vamos, esto mismo newTempArr.includes(el) ? newTempArr : [...newTempArr, el]

Verdad que se aprecia la simplicidad de los set de arriba?

Resumen

Eliminar duplicados de un array era algo complejo / ofuscado antes de tener ES6 en nuestras manos

Por qu茅?

Porque ahora podemos utilizar los sets y listos

Aunque vale la pena entender las soluciones anteriores, al menos si vamos a desarrollar con JavaScript

[ Por si te interesa, enlaces relacionados ]

Qu茅 tal la entrada?
馃憣 Bien 馃檶馃檶
馃憤 Bien, pero algunas cosas podr铆an explicarse mejor 馃槵
馃し鈥嶁檪锔 Da por sentadas demasiadas cosas 馃槖
馃し鈥嶁檪锔 A ver, hay poca chicha 馃槵
馃し鈥嶁檪锔 Los ejemplos no son muy claros 馃檱鈥嶁檪锔
馃し鈥嶁檪锔 No se entiende, est谩 mal escrito 馃憥
鉁嶏笍 Hay errores, rev铆salo en cuanto puedas 馃檹

Newsletter de kuworking, un correo de tanto en cuanto

Quiz谩 te interese

Privacidad
by kuworking.com
[ 2020 >> kuworking ]