Hamburger Icon
Uso de Sets en JavaScript

Uso de Sets en JavaScript

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.