Immutable提供了多个方法用于进行合并两个及其以上的MAP对象。然而,选择正确的方法是令人困惑的,除非你有一个非常棒的指南和丰富的例子 - 这些都是本教程的内容。
Merging Maps
将两个或更多Map合并在一起有六种不同的方法。使用它们如下:
-
originalMap.merge(Map1, Map2, Map3, ...Map-n)—— 将Maps合并在一起,将合并Maps的键/值对添加到originalMap的键/值对中,如果两个键重复,则使用最后一个Map的值。嵌套的MAP不会被合并。 -
originalMap.mergeWith((originalMapValue, mergedMapValue, key) => { /* conflict resolution */ }, Map1, Map2, Map3, ...Map-n);—— 合并多个Map,但是如果有冲突,你可以自行控制使用哪个值。 -
originalMap.mergeDeep(Map1, Map2, Map3, ...Map-n)合并嵌套的MAP -
originalMap.mergeDeepWith((originalMapValue, mergedMapValue, key) => { /* conflict resolution */ }, Map1, Map2, Map3, ...Map-n);深层次合并,如有冲突可自行控制合并值 -
const mergedMap = originalMap.mergeIn([keyPath], Map1, Map2, Map3, ...Map-n);合并keypath位置中的MAP,不合并嵌套的 -
const mergedMap = originalMap.mergeDeepIn([keyPath], Map1, Map2, Map3, ...Map-n);在由keyPath标识的位置深度合并
Map.merge()
通过将合并Map的键/值对添加到要合并到的Map的键/值对中,将两个Map合并在一起。如果任何Maps的键都相同,则将使用最后一个要合并的Map中的重复键的值。
// 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:
{
blackWidow: "Natasha Romanova",
captainAmerica: "Steve Rogers",
ironMan: "Tony Stark",
theHulk: "Bruce Banner"
}
mergeWith()
将两个或更多Map合并在一起,但是如果存在任何冲突,则可以控制使用哪个值。使用它如下:
const mergedMap = originalMap.Map((originalMapValue, mergedMapValue, key) => { /* conflict resolution */ }, mergedMap);
在下面的例子中,两个Map将被正常合并,除非:
- 合并Map的值是未定义的
- "ironMan" 为key, 这个值不能变
// 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:
{
blackWidow: "Natasha Romanova",
captainAmerica: "Steve Rogers",
ironMan: "Tony Stark",
theHulk: "Bruce Banner"
}
mergeDeep()
mergeDeep()将两个或更多的地图合并在一起,呃,深深的。使用标准的merge(),嵌套的地图不会合并在一起 - 只有顶级Map中的键合并。通过mergeDeep(),无论嵌套层次结构的深度如何,所有嵌套的地图都将被递归合并。
为了看到这一点,下面的例子显示mergeDeep()将两个复仇者合并在一起。尝试改变mergeDeep函数来合并,看看会发生什么。
// 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:
[object Object] {
heroes: [object Object] {
captainAmerica: [object Object] { ... },
ironMan: [object Object] { ... }
}
}
mergeDeepWith()
mergeDeepWith()将两个或更多的地图深度合并在一起(包括嵌套的地图),并且可以控制在合并的地图中存在重复键的情况下保留哪个值。
// 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:
{
heroes: {
captainAmerica: [object Object] {
name:"Chris Evans"
},
ironMan: [object Object] {
name:"Tony Starkless",
partner: "Pepper Potts"
}
}
}
试试将 mergeDeepWith 改为 mergeWith 看看会发生什么
mergeIn()
将两个或更多Map合并在一个嵌套Map的特定点上。使用它如下:
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:
{"heroes":{
"ironMan":{
"name":"Tony Stark",
"partner":{
"realName":"Pepper Potts",
"heroName":"hera"
}
},
"captainAmerica":{
"name":"Steve Rogers"
}
}}
mergeDeepIn()
将两个或更多嵌套的Map在嵌套的Map中的特定点合并在一起。使用它如下:
const mergedMap = originalMap.mergeDeepIn([keyPath], Map1, Map2, Map3, ...Map-n);
这与mergeIn有着微妙的差别 - 实际上,它非常微妙,我最终通过不可变的源代码寻找任何差异!
// 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:
{"heroes":{
"type":{
"human":{
"ironMan":{
"name":"Tony Stark"
},
"captainAmerica":{
"name":"Steve Rogers"
},
"blackWidow":{
"name":"Natasha Romanova"
}
},
"god":{
"thor":{"name":"Thor"}
}
}
}}