El objeto Set
Este tipo de dato tal como no lo explica la documentación oficial, es un objeto que nos permite guardar valores únicos de cualquier tipo, tanto valores primitivos como referencias de objetos o colecciones.
Lo que es muy interesante sobre este tipo de dato, es la característica de no permitirte guardar valores duplicados. Recientemente tuve que filtrar una colección en donde debía renderizar todos los valores obtenidos y evitar duplicados. A pesar de que era una cantidad relativamente baja, existía un poco de impacto en el rendimiento, el cual podría incrementarse al aumentar su longitud.
Entonces fue cuando me acordé sobre los Set en JavaScript, aunque había leído sobre ellos, nunca me di en la tarea de usarlos realmente hasta que tuve este pequeño problema de rendimiento.
El funcionamiento
Como les contaba, tenía que filtrar de una colección de datos para evitar duplicados, tal que así:
const filteredItems = arrItems
.map((item) => item.value) // filter out duplicate company names
.filter((value, index, self) => self.indexOf(value) === index);
El funcionamiento de este pequeño trozo de código es simple, pero puede conllevar problemas de optimización en el futuro porque existe una complejidad de O(n) donde n es el numero total de elementos.
Lo primero era crear una copia de los valores que quería obtener, lo cual se logra fácilmente con el método map((item) => item.value)
. Con los valores guardados, procedo a filtrarlos. Esto puede ser un poco más complejo, pero si lo destructuramos, es fácil de entender.
Basicamente al preguntar por el índice del elemento self.indexOf(value)
y compararlo con el index
, agregrará el primer elemento que encuentre. La segunda vez que se realice la comparación, verificará el índice del elemento repetido con el índice del primer elemento, lo cuál será falso y por lo tanto no será añadido.
Recuerda que con el método filter()
tenemos acceso en el momento de la iteración a: elemento o valor (value)
, al índice del elemento o valor (index)
y por último a la colección de datos sobre la que iteramos (self)
.
Implementamos un Set
Ahora para mejorar este código implementaremos los Object Set, primero declaramos una variable definiendo el tipo de dato.
const values = new Set()
Y ahora mediante un forEach()
añadiremos los valores.
arrItems.forEach((item) => values.add(item.value));
Perfecto. La razón de no usar map()
es porque ya no necesitamos crear una copia. Con el método forEach
estamos añadiendo esos valores por medio del método add()
a nuestro new Set
. Bien ya con esto en teoría debería ir mejor, pero falta la mejor parte.
Filtrar valores duplicados en un Set
Pues ahora nos queda por hacer lo último, que sería filtrar los valores duplicados. Aunque si estuviste prestando atención ya te habrás dado cuenta que ¡No es necesario! Así es, cuando intentamos añadir un valor duplicado, simplemente lo ignora y no hace ningún cambio. Por lo tanto, el filtrado de duplicados aquí directamente nos lo saltamos... ¡Genial! ¿No crees?
Ejemplo
const set = new Set();
// Añadir valores al Set
set.add(1);
set.add(2);
set.add(3);
set.add(2); // Intentar añadir un valor repetido
console.log([...set]); // [1, 2, 3]