How do javascript Map objects work?

Today I’ve been struggling with manipulating a dataset in a tool I’ve been working on that makes use of javascript Map object as kindly introduced into the code base by one of my colleagues at work.

I have very little experience using Maps as I generally get by my data manipulation requirements using arrays combined with map, filter and reduce methods combined with spread operators, or vanilla javascript objects with Object.keys(objName). Maps seem to be a whole together different beast to the types I have experienced in Python and I think this is why I’ve struggled to get to grips with them. Today I decided to get my head round them and and write some useful tips while using them.

//create a simple Map
const map1 = new Map([[1, "a"]]);
//returns Map(1) {1 => "a"}

//extract the value
mapValue = map1.get(1); //returns "a"

The above very simple example demonstrates the method for retrieving data from a Map object. Introducing a second Map does not increase difficulty, however when the keys are identical it becomes a little trickier.

const map2 = new Map([[2, "b"]]);
const combinedMap = new Map([...map1,...map2]); //spread operator keeps things simple 
combinedMap.get(2) // returns "b"

const map3 = new Map([[2, "c"]]);
const newCombinedMap = new Map([...map1,...map2, ...map3]);
newCombinedMap.get(2); //returns "c"

As you can see when creating newCombinedMap above, the value from map3 overrides the value of map2. This is because Map can only contain unique keys. More info can be found in the docs linked earlier, but all we need to understand is that the final value makes the output.

Today I wanted to append the data from a second Map onto the data already present in the first Map for the same key. Unfortunately the official docs did not seem to cover this type of example. I’ve tried to demonstrate a simple version of the problem below and my resulting workaround:

const map1 = new Map([['data', [1,2,3,4,5]]]);
const map2 = new Map([['data', [6,7,8,9,10]]]);

//target result: {"data" => [1,2,3,4,5,6,7,8,9,10]}

const bothMaps = new Map([...map1, ...map2]); //returns {"data" => [6,7,8,9,10]}

const map1Arr = Array.from(map1); //return ['data',[1,2,3,4,5]]
const map2Arr = Array.from(map2); //return ['data',[6,7,8,9,10]]

//create a single array to feed new Map
const combinedArr = map1Arr.map((x,i) => [x[0], [...x[1], ...map2Arr[i][1]]]); // return ['data', [1,2,3,4,5,6,7,8,9,10]]

const bothMapsWorking = new Map([...combinedArr]); //returns {"data" => [1,2,3,4,5,6,7,8,9,10]

The above demonstrates how you might combine two Maps with identical keys. It will also work where map1 and map2 contain multiple keys. To handle multiple keys that are not identical you just need to take advantage of the Map creation method ensuring you spread the combinedArr last. And if the keys are not in the same order within your Map or derived arrays, then you can search for the key using .filter array method.

const map1 = new Map([['dataset1', [1,2,3,4,5]]]);
const map2 = new Map([['dataset1', [6,7,8,9,10]]]); 
const map3 = new Map([['dataset1', [11,12]],['dataset2',[13,14]]]); 

const map1Arr = Array.from(map1);
const map2Arr = Array.from(map2);
const map3Arr = Array.from(map3); //contains extra map key

const combinedArr = map1Arr.map((x,i) => [x[0], [...x[1], ...map2Arr[i][1], ...map3Arr[i][1]]]);

const singleMap = new Map([...map3Arr, ...combinedArr]); //returns: Map(2) {"dataset1" => Array(2), "dataset2" => Array(2)}

Leave a comment