Estoy trabajando bastante con Maps en javascript. Necesito la forma más eficiente desde el punto de vista computacional para encontrar todos los elementos que están en el Mapa a que no están presentes en el Mapa b. Por ejemplo,
const a = new Map(); a.set('item1', 'item1value'); a.set('item2', 'item2value'); const b = new Map(); b.set('item1', 'item1value'); El resultado de la función que busco escribir sería otro Map, con una sola entrada de key: item2 , value: item2value .
Soy muy consciente de la multitud de preguntas/respuestas/métodos para hacer esto con matrices y objetos, sin embargo, no he visto tal explicación para los mapas. Necesito la forma más eficiente de hacerlo, ya que tendré que llamar a esta función miles de veces rápidamente. ¿Es la conversión a una matriz y de regreso a un Mapa la mejor manera? ¿Hay algún truco con Maps que pueda ayudar?
No, no convierta los mapas en matrices y viceversa. Calcular la diferencia entre matrices es lento, en un mapa tiene una búsqueda O(1) . Simplemente recorra las entradas de a y colóquelas en el resultado si no encuentra una entrada equivalente en b . Esto tendrá la complejidad de tiempo óptima O(n) (donde n es el tamaño del mapa a ).
const result = new Map(); for (const [k, v] of a) { if (v === undefined && !b.has(k) || b.get(k) !== v) { result.set(k, v); } } Si sabe que su mapa no contiene valores undefined , puede omitir v === undefined && !b.has(k) || por completo y podría obtener algo de aceleración. Además, tenga en cuenta que si su mapa puede contener valores NaN , querrá usar Object.is en lugar de === .
Si desea escribirlo como una sola expresión elegante, considere un generador:
const result = new Map(function*() { for (const e of a) { const [k, v] = e; if (v === undefined && !b.has(k) || b.get(k) !== v) { yield e; } } }());Puede iterar el primer mapa y compararlo con el segundo.
const a = new Map([['item1', 'item1'], ['item2', 'item2']]), b = new Map([['item1', 'item1']]), difference = (a, b) => { const d = new Map; a.forEach((v, k) => { if (!b.has(k) || b.get(k) !== v) d.set(v, k); }); return d; } console.log([...difference(a, b)])Tal vez así manteniendo a ;
var a = new Map(), b = new Map(), c; a.set('item1', 'item1value'); a.set('item2', 'item2value'); b.set('item1', 'item1value'); c = new Map(a); b.forEach((_,k) => c.delete(k)); console.log(c); // try in dev tools to see result