Immutable offers many different ways of merging two or more Maps together. Choosing the right way, though, is confusing, unless you have an awesome guide with copious examples – which, funnily enough, is what this tutorial is.
Merging Maps
There are six different ways to merge two or more Maps together. Use them as follows:
originalMap.merge(Map1, Map2, Map3, ...Map-n)
– merges Maps together adding the key/value pairs of the merging Maps to those of the originalMap. If two keys are duplicated, the last Map’s value is used. Nested Maps are notmerged.originalMap.mergeWith((originalMapValue, mergedMapValue, key) => { /* conflict resolution */ }, Map1, Map2, Map3, ...Map-n);
– merges Maps, but lets you control which value to use if there are any conflicts;originalMap.mergeDeep(Map1, Map2, Map3, ...Map-n)
– merges Maps, including nested Maps;originalMap.mergeDeepWith((originalMapValue, mergedMapValue, key) => { /* conflict resolution */ }, Map1, Map2, Map3, ...Map-n);
– merges Maps deeply, but lets you control which value to use if there are any conflicts;const mergedMap = originalMap.mergeIn([keyPath], Map1, Map2, Map3, ...Map-n);
– merges Maps at the location identified bykeyPath
. Does not merge nested Maps.const mergedMap = originalMap.mergeDeepIn([keyPath], Map1, Map2, Map3, ...Map-n);
– merges nested Maps deeply at the location identified bykeyPath
Map.merge()
Merge two Maps together by adding the key/value pairs of the merging Maps to those of the Map being merged into. If the keys of any of the Maps are the same, the value of the duplicate key in the last Map to be merged in will be used.
// Merge
const avengers = Immutable.Map({
ironMan: 'Tony Stark',
captainAmerica: 'Steve Rogers'
});
const mergingAvengers = Immutable.Map({
blackWidow: 'Natasha Romanova',
theHulk: 'Bruce Banner'
});
const mergedAvengers = avengers.merge(mergingAvengers);
// Output:
mergedAvengers;
mergeWith()
Merges two or more Maps together, but lets you control which value to use if there are any conflicts. Use it as follows:
const mergedMap = originalMap.Map((originalMapValue, mergedMapValue, key) => { /* conflict resolution */ }, mergedMap);
In the example below, the two Maps will be merged as normal, unless:
- the merging Map’s value is undefined
- the key is ‘ironMan’. His value must never be changed. He is immutable!
// Merge two Maps using mergeWith
const avengers = Immutable.Map({
ironMan: 'Tony Stark',
captainAmerica: undefined,
blackWidow: 'Natasha Romanova',
});
const mergingAvengers = Immutable.Map({
theHulk: 'Bruce Banner',
blackWidow: undefined,
ironMan: 'imposter!',
captainAmerica: 'Steve Rogers',
});
const mergedAvengers = avengers.mergeWith((prev, next, key) => {
// If mergingMap's value is undefined, return the originalMap's value
if(!next) {
return prev;
}
// If the key = 'ironMan', then use the originalMap's value
if(key==='ironMan') {
return prev;
}
// otherwise, use the mergingMap's value
return next;
}, mergingAvengers);
// Output:
mergedAvengers;
mergeDeep()
mergeDeep()
merges two or more Maps together, er, deeply (again, the clue’s in the title!). With standard merge()
, nested Maps are not merged together – only the keys in the top-level Map are merged. With mergeDeep()
, all nested Maps are merged recursively, regardless of their depth in the nesting hierarchy.
To see this in action, the example below shows mergeDeep()
merging two Avengers together. Try changing the mergeDeep
function to merge
and see what happens.
// Merge two Maps using mergeDeep
const ironMan = Immutable.fromJS({
heroes: {
ironMan: {
name: 'Tony Stark'
},
captainAmerica: {
name: 'Steve Rogers'
}
}
});
const mergingMan = Immutable.fromJS({
heroes: {
ironMan: {
partner: 'Pepper Potts'
}
}
});
const mergedMan = ironMan.mergeDeep(mergingMan);
// Output:
mergedMan;
mergeDeepWith()
mergeDeepWith()
deeply merges two or more Maps together (including nested Maps), and lets you control which value to keep should there be duplicate keys in the Maps being merged.
// Merge two Maps using mergeDeepWith
const avengers = Immutable.fromJS({
heroes: {
ironMan: {
name: 'Tony Stark'
},
captainAmerica: {
name: 'Steve Rogers'
}
}
});
const mergingAvengers = Immutable.fromJS({
heroes: {
ironMan: {
name: 'Tony Starkless',
partner: 'Pepper Potts'
},
captainAmerica: {
name: 'Chris Evans'
}
}
});
const mergedAvengers = avengers.mergeDeepWith((prev, next, key) => {
// If the key = 'name', then use the originalMap's value
if(key==='ironMan') {
return prev;
}
// otherwise, use the mergingMap's value
return next;
}, mergingAvengers);
// Output:
mergedAvengers;
Again, try changing mergeDeepWith
with mergeWith
and see what happens.
mergeIn()
Merges two or more Maps together at a specific point in a nested Map. Use it as follows:
const mergedMap = originalMap.mergeIn([keyPath], Map1, Map2, Map3, ...Map-n);
// Merge two Maps using mergeIn
const avengers = Immutable.fromJS({
heroes: {
ironMan: {
name: 'Tony Stark'
},
captainAmerica: {
name: 'Steve Rogers'
}
}
});
const mergingAvengers = Immutable.fromJS({
partner: {
realName: 'Pepper Potts',
heroName: 'hera'
}
});
const mergedAvengers = avengers.mergeIn(['heroes', 'ironMan'], mergingAvengers);
// Output:
mergedAvengers;
mergeDeepIn()
Merges two or more nested Maps together at a specific point in a nested Map. Use it as follows:
const mergedMap = originalMap.mergeDeepIn([keyPath], Map1, Map2, Map3, ...Map-n);
This is subtly different from mergeIn
– indeed, it’s so subtle, I ended up looking through the Immutable source code looking for any differences!
They are there though. Change the following example from mergeDeepIn
to mergeIn
and see what happens.
// Merge two Maps using mergeDeepIn
const avengers = Immutable.fromJS({
heroes: {
type: {
human: {
ironMan: {
name: 'Tony Stark'
},
captainAmerica: {
name: 'Steve Rogers'
}
},
god: {
thor : {
name: 'Thor'
}
}
},
}
});
const mergingAvengers = Immutable.fromJS({
human :{
blackWidow: {
name: 'Natasha Romanova'
}
}
});
const mergedAvengers = avengers.mergeDeepIn(['heroes', 'type'], mergingAvengers);
// Output:
mergedAvengers;
All Immutable.js Tutorials in this Series
This is just one tutorial in this in-depth series of Immutable.js tutorials. Here are the others, which all contain a wealth of information and examples (and all in JavaScript!).
Introduction
Lists
- The Foolproof Guide to Creating Lists
- Get, Set and Delete data from an Immutable List
- Merging Lists Finally Explained
Maps
- Every Way to Create an Immutable.js Map
- Get, Set, Delete and Update data from an Immutable Map
- 6 Ways to Merge Maps in Immutable.js