Objeto Map

El objeto Map almacena pares clave-valor. Cualquier valor (objeto o valor primitivo) puede usarse como clave o como valor.

Diferencia entre Maps y Objects

  • Las claves de un Object solo pueden ser cadenas (strings) o Symbols, pero las claves de un Map pueden ser cualquier valor.
  • Las claves en un Map están ordenadas (principio FIFO), mientras que las claves añadidas a un objeto no lo están.
  • El número de pares clave-valor de un Map se puede obtener de la propiedad size, mientras que el número de pares clave-valor de un Object solo se puede calcular manualmente.
  • Object tiene su propio prototipo; los nombres de las claves en la cadena de prototipos pueden entrar en conflicto con los nombres que estableces tú mismo en el objeto.

key en Map

La key es una cadena

var myMap = new Map(); var keyString = "a string"; myMap.set(keyString, "El valor asociado a la clave 'a string'"); myMap.get(keyString); //"El valor asociado a la clave 'a string'" myMap.get("a string"); //"El valor asociado a la clave 'a string'" //Porque keyString === 'a string'

La key es un objeto

var myMap = new Map(); var keyObj = {}, myMap.set(keyObj, "El valor asociado a la clave keyObj");  myMap.get(keyObj); //"El valor asociado a la clave keyObj" myMap.get({}); //undefined, porque keyObj !== {}

La key es una función

var myMap = new Map(); var keyFunc = function () {}, //función myMap.set(keyFunc, "El valor asociado a la clave keyFunc"); myMap.get(keyFunc); //"El valor asociado a la clave keyFunc" myMap.get(function() {}) //undefined, porque keyFunc !== function () {}

La key es NaN

var myMap = new Map(); myMap.set(NaN, "not a number"); myMap.get(NaN); // "not a number" var otherNaN = Number("foo"); myMap.get(otherNaN); // "not a number"

Aunque NaN no es igual a ningún valor, ni siquiera a sí mismo (NaN !== NaN devuelve true), como clave de Map no hay diferencia.

Iteración de Map

Para recorrer un Map, las siguientes dos son las más avanzadas.

for...of

var myMap = new Map(); myMap.set(0, "zero"); myMap.set(1, "one"); //Mostrará dos logs. Uno es "0 = zero" y el otro es "1 = one" for (var [key, value] of myMap) {   console.log(key + " = " + value); } for (var [key, value] of myMap.entries()) { console.log(key + " = " + value); } /*El método entries devuelve un nuevo objeto Iterator que contiene, en orden de inserción, los arreglos [key, value] de cada elemento del objeto Map.*/ //Mostrará dos logs. Uno es "0" y el otro es "1" for (var key of myMap.keys()) {   console.log(key); } /*El método keys devuelve un nuevo objeto Iterator que contiene, en orden de inserción, las claves de cada elemento del objeto Map.*/ //Mostrará dos logs. Uno es "zero" y el otro es "one" for (var value of myMap.values()) {   console.log(value); } /*El método values devuelve un nuevo objeto Iterator que contiene, en orden de inserción, los valores de cada elemento del objeto Map.*/

forEach()

var myMap = new Map(); myMap.set(0, "zero"); myMap.set(1, "one"); //Mostrará dos logs. Uno es "0 = zero" y el otro es "1 = one" myMap.forEach(function(value, key) { console.log(key + " = " + value); }, myMap)

Operaciones del objeto Map

Conversión entre Map y Array

var kvArray = [["key1", "value1"], ["key2", "value2"]]; //El constructor de Map puede convertir un arreglo bidimensional de pares clave-valor en un objeto Map. var myMap = new Map(kvArray); //Usando la función Array.from se puede convertir un objeto Map en un arreglo bidimensional de pares clave-valor. var outArray = Array.from(myMap);

Clonación de Map

var myMap1 = new Map([["key1", "value1"], ["key2", "value2"]]); var myMap2 = new Map(myMap1); console.log(original === clone); //Imprime false. El constructor del objeto Map genera una instancia e itera para generar un nuevo objeto.

Combinación de Map

var first = new Map([[1, 'one'], [2, 'two'], [3, 'three'],]); var second = new Map([[1, 'uno'], [2, 'dos']]); //Al combinar dos objetos Map, si hay claves duplicadas, la última sobrescribe a la primera; los valores correspondientes son uno, dos, three. var merged = new Map([...first, ...second]);

Objeto Set

El objeto Set te permite almacenar valores únicos de cualquier tipo, ya sean valores primitivos u referencias a objetos.

Valores especiales en Set

Los valores almacenados en un objeto Set son siempre únicos, por lo que es necesario determinar si dos valores son estrictamente iguales. Hay algunos valores especiales que requieren un tratamiento especial:

  • +0 y -0 son estrictamente iguales al juzgar la unicidad en el almacenamiento, por lo que no se repiten;
  • undefined y undefined son estrictamente iguales, por lo que no se repiten;
  • NaN y NaN no son estrictamente iguales, pero en un Set solo se puede almacenar uno, no se repite.

Código

let mySet = new Set(); mySet.add(1); // Set(1) {1} mySet.add(5); // Set(2) {1, 5} mySet.add(5); //Set(2) {1, 5} Aquí se refleja la unicidad de los valores. mySet.add("some text"); //Set(3) {1, 5, "some text"} Aquí se refleja la diversidad de tipos. var o = {a: 1, b: 2}; mySet.add(o); mySet.add({a: 1, b: 2}); // Set(5) {1, 5, "some text", {…}, {…}} //Aquí se refleja que las referencias entre objetos son diferentes y no son estrictamente iguales; incluso si los valores son iguales, Set puede almacenarlos.

Conversión de tipos

Array

//Convertir Array a Set var mySet = new Set(["value1", "value2", "value3"]); //Con el operador ..., convertir Set a Array. var myArray = [...mySet]; String //Convertir String a Set var mySet = new Set('hello');  // Set(4) {"h", "e", "l", "o"} //Nota: el método toString en Set no puede convertir Set a String.

Utilidad del objeto Set

Eliminar duplicados de un array

var mySet = new Set([1, 2, 3, 4, 4]); [...mySet]; // [1, 2, 3, 4]

Unión

var a = new Set([1, 2, 3]); var b = new Set([4, 3, 2]); var union = new Set([...a, ...b]); // {1, 2, 3, 4}

Intersección

var a = new Set([1, 2, 3]); var b = new Set([4, 3, 2]); var intersect = new Set([...a].filter(x => b.has(x))); // {2, 3}

Diferencia

var a = new Set([1, 2, 3]); var b = new Set([4, 3, 2]); var difference = new Set([...a].filter(x => !b.has(x))); // {1}