Los sets son una de esas opciones que tenemos en JavaScript que quizás no sepamos que están ahí y pueden sernos de gran ayuda. Vamos a ver qué son y cómo usarlos.
Los sets son colecciones de valores, como los arrays, pero a diferencia de estos, los sets no permiten duplicados. Son ideales cuando queremos una colección de elementos sin duplicados.
En un set podemos meter cualquier tipo de valor, y se crea de esta forma:
const gruposRock = ["Led Zeppelin", "Deep Purple", "The Doors"] /* Para crear el set podemos pasar como parámetros: - cualquier objeto iterable - null / no pasar ningún valor (set vacío) */ const miSet = new Set(gruposRock)
Operaciones básicas con un set
Los sets son ligeramente diferentes a los arrays, pero podemos hacer operaciones similares, como añadir o quitar elementos, obtener su tamaño, comprobar si un elemento existe en el set...
const gruposRock = ["Led Zeppelin", "Deep Purple", "The Doors"] // creamos el set const miSet = new Set(gruposRock) // añadimos elementos miSet.add("Los Chunguitos") miSet.add("Héroes del Silencio") // tamaño del set console.log(miSet.size) // 5 // eliminamos elementos miSet.delete("Los Chunguitos") console.log(miSet.size) // 4 // comprobamos si existe un elemento en el set console.log(miSet.has("Led Zeppelin")) // true console.log(miSet.has("Los Chunguitos")) // false // eliminamos todos los elementos del set miSet.clear() console.log(miSet.size) // 0
Iterando los elementos de un set
Para iterar un set podemos usar su método forEach:
const gruposRock = ["Led Zeppelin", "Deep Purple", "The Doors"] // creamos el set const miSet = new Set(gruposRock) // iteramos con forEach miSet.forEach((grupo) => console.log(grupo)) // imprime los 3 grupos
O bien con un bucle *for..of:*
const gruposRock = ["Led Zeppelin", "Deep Purple", "The Doors"] // creamos el set const miSet = new Set(gruposRock) /* iteramos con for..of miSet.values() devuelve un iterable con los valores del set */ for (const grupo of miSet.values()) { console.log(grupo) // imprime los 3 grupos }
¿Puedo usar las funciones map, filer y reduce?
No, sobre un set no puedes usar esas funciones, están solo disponibles para los arrays. Por lo tanto, si quieres usar alguna de estas funciones tendrás que transformar el set en array primero, para eso es muy útil la sintaxis spread:
const gruposRock = ["Led Zeppelin", "Deep Purple", "The Doors"] // creamos el set const miSet = new Set(gruposRock) // con la sintaxis spread se transforma el set en array // y obtenemos un array como resultado const resultadoArray = [...miSet].map((grupo) => { // lógica del bucle return `Grupo de rock ${grupo}` }) // para trabajar de nuevo con un set, lo recreamos a partir del array const miNuevoSet = new Set(resultadoArray)
Eliminar duplicados en un array
Si ya tienes un array y simplemente quieres eliminar los duplicados del mismo, con los sets lo haces en un momento:
// array original con elementos duplicados const arrayDeNumeros = [1, 2, 3, 4, 5, 2, 4, 5] // creamos un set y con la sintaxis spread devolvemos // el array sin duplicados const arraySinRepetidos = [...new Set(arrayDeNumeros)] console.log(arraySinRepetidos) // [1, 2, 3, 4, 5]
Ten en cuenta los casos especiales de objetos y arrays
Aunque parezca raro, en JavaScript pasa esto:
const objeto1 = { id: 1, nombre: "Led Zeppelin" } const objeto2 = { id: 1, nombre: "Led Zeppelin" } const array1 = [1, 2, 3] const array2 = [1, 2, 3] // estas comparaciones siempre serán falsas console.log(objeto1 === objeto2) // false console.log(array1 === array2) // false
Esto es debido a que las variables que almacenan los objetos y lo arrays los que guardan es una referencia al mismo, no su valor. Por eso la comparación siempre es falsa. Teniendo en cuenta esto, si creamos un set con todos estos objetos, será un set de 4 elementos:
const objeto1 = { id: 1, nombre: "Led Zeppelin" } const objeto2 = { id: 1, nombre: "Led Zeppelin" } const array1 = [1, 2, 3] const array2 = [1, 2, 3] const miSet = new Set() miSet.add(objeto1) miSet.add(objeto2) miSet.add(array1) miSet.add(array2) // contiene duplicados console.log(miSet.size) // 4
En estas situaciones, tendremos que iterar el set y eliminar los duplicados de forma manual.
¿Verdad que los sets son útiles? Si necesitas guardar una colección sin duplicados, son la herramienta perfecta. Hemos visto que además podemos aprovechar los métodos map, filter y reduce con el truco de convertir el set en array y viceversa.
Lo único que tendremos que tener en cuenta es que deberemos ir con cuidado cuando almacenemos objetos y arrays, ya que seremos responsables de hacer las comprobaciones necesarias para evitar duplicados.