Map y Set en JavaScript
Hasta ahora, hemos aprendido sobre las siguientes estructuras de datos en JavaScript:
- Objetos para almacenar colecciones de datos organizadas por claves.
- Arrays para guardar colecciones ordenadas de elementos.
Sin embargo, en situaciones del mundo real, estas estructuras no siempre son suficientes. Por eso, existen también Map
y Set
.
Map
Map
, similar a un objeto, es una colección de datos identificados por claves. La diferencia principal es que Map
permite usar claves de cualquier tipo.
Métodos y propiedades de Map
:
new Map()
– crea un nuevoMap
.map.set(key, value)
– guarda el valor asociado a la clave.map.get(key)
– devuelve el valor de la clave, oundefined
si la clave no existe.map.has(key)
– verifica si la clave existe en elMap
, devuelvetrue
ofalse
.map.delete(key)
– elimina el elemento con la clave especificada.map.clear()
– elimina todos los elementos delMap
.map.size
– devuelve el número de elementos en elMap
.
Ejemplo de uso:
let map = new Map();
map.set('1', 'str1'); // una cadena como clave
map.set(1, 'num1'); // un número como clave
map.set(true, 'bool1'); // un booleano como clave
// A diferencia de los objetos, las claves en Map no se convierten a strings.
console.log( map.get(1) ); // 'num1'
console.log( map.get('1') ); // 'str1'
console.log( map.size ); // 3
Podemos ver que Map
mantiene el tipo de las claves, a diferencia de los objetos que las convierten en strings.
Usar objetos como claves:
let john = { name: "John" };
// Creamos un Map para almacenar el recuento de visitas
let visitsCountMap = new Map();
visitsCountMap.set(john, 123);
console.log( visitsCountMap.get(john) ); // 123
En este ejemplo, john
es la clave del Map
. Los objetos no pueden ser usados como claves en objetos normales, pero sí en Map
.
Comparación de claves en Map
:
Para comparar claves, Map
utiliza el algoritmo SameValueZero
, que es similar a la igualdad estricta (===
), pero trata NaN
como igual a NaN
.
Encadenamiento de métodos:
Cada llamada a map.set
devuelve el propio map
, permitiendo encadenar las llamadas:
map.set('1', 'str1')
.set(1, 'num1')
.set(true, 'bool1');
Iteración sobre Map
:
Podemos iterar sobre un Map
utilizando tres métodos:
map.keys()
– devuelve un iterable de las claves.map.values()
– devuelve un iterable de los valores.map.entries()
– devuelve un iterable de las entradas[clave, valor]
. Este es el método utilizado por defecto enfor..of
.
Ejemplo de iteración:
let recipeMap = new Map([
['pepino', 500],
['tomates', 350],
['cebollas', 50]
]);
// Iterar sobre las claves
for (let vegetable of recipeMap.keys()) {
console.log(vegetable); // pepino, tomates, cebollas
}
// Iterar sobre los valores
for (let amount of recipeMap.values()) {
console.log(amount); // 500, 350, 50
}
// Iterar sobre las entradas [clave, valor]
for (let entry of recipeMap) { // lo mismo que recipeMap.entries()
console.log(entry); // ['pepino', 500], etc.
}
La iteración en un Map
sigue el orden de inserción.
Map
también incluye el método forEach
, similar al de los arrays:
recipeMap.forEach((value, key, map) => {
console.log(`${key}: ${value}`); // pepino: 500, etc.
});
Crear Map
a partir de un objeto:
Podemos inicializar un Map
a partir de un array de pares [clave, valor]
:
let map = new Map([
['1', 'str1'],
[1, 'num1'],
[true, 'bool1']
]);
console.log( map.get('1') ); // str1
Si tenemos un objeto simple, podemos convertirlo en un Map
utilizando Object.entries
:
let obj = {
name: "John",
age: 30
};
let map = new Map(Object.entries(obj));
console.log( map.get('name') ); // John
Convertir Map
en un objeto:
Podemos convertir un Map
en un objeto simple usando Object.fromEntries
:
let map = new Map();
map.set('banana', 1);
map.set('orange', 2);
map.set('meat', 4);
let obj = Object.fromEntries(map.entries()); // convierte a objeto simple
console.log(obj.orange); // 2
Set
Un Set
es una colección especial de valores únicos, es decir, cada valor solo puede aparecer una vez.
Métodos y propiedades de Set
:
new Set([iterable])
– crea un nuevoSet
. El argumento opcional es un objeto iterable (generalmente un array) con valores para inicializar elSet
.set.add(value)
– añade un valor y devuelve elSet
.set.delete(value)
– elimina un valor, devuelvetrue
si el valor existía yfalse
si no.set.has(value)
– devuelvetrue
si el valor existe en elSet
, de lo contrariofalse
.set.clear()
– elimina todos los valores delSet
.set.size
– devuelve el número de valores en elSet
.
Ejemplo de uso:
let set = new Set();
let john = { name: "John" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };
// Añadir valores, algunos repetidos
set.add(john);
set.add(pete);
set.add(mary);
set.add(john);
set.add(mary);
// Set almacena solo valores únicos
console.log(set.size); // 3
for (let user of set) {
console.log(user.name); // John, Pete, Mary
}
Iteración sobre Set
:
Podemos iterar sobre un Set
usando for..of
o forEach
:
let set = new Set(["oranges", "apples", "bananas"]);
for (let value of set) {
console.log(value);
}
// Igual que forEach:
set.forEach((value, valueAgain, set) => {
console.log(value);
});
Resumen
Map
- Propósito: Colección de pares clave-valor.
- Métodos principales:
set
,get
,has
,delete
,clear
,size
. - Diferencias con Object: Permite claves de cualquier tipo, métodos adicionales, mantiene el orden de inserción.
Set
- Propósito: Colección de valores únicos.
- Métodos principales:
add
,delete
,has
,clear
,size
. - Iteración: Siempre en orden de inserción. Soporta
for..of
,forEach
,keys
,values
,entries
.
Ambas estructuras son útiles para manejar datos de forma más flexible y eficiente en JavaScript.