Map y Set

<< Desestructuración Clases y objetos >>

Diccionario (Map)

Un diccionario (Map) es una colección que guarda parejas de [clave,valor], los valores son accedidos usando la correspondiente clave. En JavaScript, un objeto podría ser considerado como un tipo de Mapa pero con algunas limitaciones (Sólo con strings y enteros como claves).

La colección Map permite usar cualquier objeto como clave. Creamos la colección usando el constructor new Map(), y podemos usar los métodos set, get y delete para almacenar, obtener o eliminar un valor a partir de su clave.

let person1 = {name: "Peter", age: 21};
let person2 = {name: "Mary", age: 34};
let person3 = {name: "Louise", age: 17};

let hobbies = new Map(); // Almacenará una persona con un array de hobbies (string)
hobbies.set(person1, ["Tennis", "Computers", "Movies"]);
console.log(hobbies); // Map {Object {name: "Peter", age: 21} => ["Tennis", "Computers", "Movies"]}

hobbies.set(person2, ["Music", "Walking"]);
hobbies.set(person3, ["Boxing", "Eating", "Sleeping"]);
console.log(hobbies);

Al igual que ocurre al asignar un objeto a una variable, array, parámetro de función, etc., cuando usamos un objeto como clave, debemos saber que almacenamos una referencia a ese objeto. Por tanto, se debe usar la misma referencia para acceder a su valor, modificarlo, o para eliminarlo.

console.log(hobbies.has(person1)); // true (referencia al objeto original almacenado)
console.log(hobbies.has({name: "Peter", age: 21})); // false (mismas propiedades pero objeto diferente!)

La propiedad size devuelve la longitud del mapa y podemos iterar a través por él usando el bucle for..of o el método forEach. En el primer caso, para cada iteración, se devuelve un array con dos posiciones: 0 → key, y 1 → value.

 // Continuamos con el código anterior
console.log(hobbies.size); // Imprime 3
hobbies.delete(person2); // Elimina person2 del Map
console.log(hobbies.size); // Imprime 2
console.log(hobbies.get(person3)[2]); // Imprime "Sleeping"

/** Recorremos Map y lo imprimimos:
 * Peter: Tennis, Computers, Movies
 * Louise: Boxing, Eating, Sleeping */
for(let entry of hobbies) {
    console.log(entry[0].name + ": " + entry[1].join(", "));
}

for(let [person, hobArray] of hobbies) { // Mejor
    console.log(person.name + ": " + hobArray.join(", "));
}

hobbies.forEach((hobArray, person) => { // Mejor
    console.log(person.name + ": " + hobArray.join(", "));
});

Conjunto (Set)

La colección Set es similar a Map internamente, pero no almacena la parte del valor (sólo la clave). Puede ser visto como una colección que no permite valores duplicados (en un array puede haber valores duplicados). Es una colección bastante simple que solo tiene métodos como add, delete y has, que devuelven un booleano y sirven para almacenar, borrar y comprobar si existe un valor.

Internamente un conjunto no almacena los valores en posiciones marcadas por un índice como el Array. Esto implica, al igual que con la colección Map, que los valores no se tienen por qué recorrer en el orden que se insertaron.

let set = new Set();
set.add("John");
set.add("Mary");
set.add("Peter");
set.delete("Peter");
console.log(set.size); // Imprime 2

set.add("Mary"); // Mary ya existe
console.log(set.size); // Imprime 2

// Itera a través de los valores
set.forEach(value => {
    console.log(value);
})

Podemos crear un Set desde un array (lo cual elimina los valores duplicados).

let names = ["Jennifer", "Alex", "Tony", "Johny", "Alex", "Tony", "Alex"];
let nameSet = new Set(names);
console.log(nameSet); // Set {"Jennifer", "Alex", "Tony", "Johny"}
names = [...nameSet]; // Reasignamos el array con los duplicados eliminados

<< Desestructuración Clases y objetos >>