在之前的文章中,我們已經看到了如何創建一個新的列表,以及如何添加,插入和刪除項目。現在是時候學習更高級一點的技能了 —— 合並兩個或更多列表的方式。
注意:記住Immutable不會改變任何被合並的列表。合並列表總是從任何合並函數返回,使合並操作中涉及的任何列表完全不變。因此,無論何時您看到諸如“合並列表...”或“覆蓋originalList”之類的詞組,它都是被包含的列表的副本,這些副本正在發生變化(並最終作為合並列表返回)。
列表的4個合並功能
Immutable提供了四個獨立的合並函數:
originalList.merge(List1, List2, List3...List-n)
通過用List1(和List2,List3 ... List-n)中的項目覆蓋originalList
的相應位置上的每個項目,返回合並列表。mergeWith(conflictResolutionFn, List1, List2, List3...List-n)
將列表合並在一起,但使用傳入的conflictResolutionFn()來解決沖突.mergeDeep(List1, List2, List3...List-n)
將列表合並在一起,如果存在沖突,則合並沖突項目mergeDeepWith(conflictResolutionFn, List1, List2, List3...List-n)
將列表合並在一起,如果存在沖突,則使用傳入的conflictResolutionFn()來解決沖突。
以下是如何使用這些功能。
merge()
合並兩個列表
merge()
使用合並列表中存在於相應索引處的值覆蓋List中每個項目的值。
// Merge two lists together with merge
const oldAvengers = Immutable.List(['ironMan', 'captainAmerica', 'theHulk']);
const newAvengers = Immutable.List(['scarletWitch', 'vision']);
// Merge all the lists!
oldAvengers.merge(newAvengers);
這是發生了什么事情:
oldAvengers[0] = 'ironMan'
newAvengers[0] = 'scarletWitch'
- 列表中的每個項目(即oldAvengers)的值被相應索引(即索引0)處的合並列表(即newAvengers)中的值覆蓋。
- 所以,'scarletWitch'(newAvengers [0]處的值)會覆蓋'ironMan'(oldAvengers [0]處的值)。 'vision'重寫'captainAmerica';但新的newAvengers[2]並不存在,所以oldAvengers[2](即“theHulk)保持不變。
將兩個以上的列表合並在一起
將兩個以上的列表合並在一起時,列表將依次合並,最后一個列表最終將覆蓋所有以前的列表。
// Merge more than one List together
const oldAvengers = Immutable.List(['ironMan', 'captainAmerica', 'theHulk']);
const newAvengers = Immutable.List(['scarletWitch', 'vision']);
const newerAvengers = Immutable.List(['antMan']);
// Merge all the lists!
oldAvengers.merge(newAvengers, newerAvengers);
mergeWith()
mergeWith()
讓您提供自己的沖突解決功能,這樣您就可以使合並更加智能化,而不僅僅是通過索引值覆蓋,並且更加具體地滿足您的需求。使用方法:
list1.mergeWith(conflictResolutionFn(list1Value, list2Value, index){}, list2)
示例
1、合並列表並根據項目值解決沖突
// Merge lists only if item is not null with mergeWith()
const oldAvengers = Immutable.List(['ironMan', 'captainAmerica', 'theHulk']);
const newAvengers = Immutable.List(['scarletWitch', null, 'vision']);
// Merge only if newAvenger value is not null
oldAvengers.mergeWith((oldAvenger, newAvenger, index) => {
return (newAvenger === null) ? oldAvenger : newAvenger
}, newAvengers);
2、根據索引合並列表並解決沖突
// Merge every other List item with mergeWith()
const oldAvengers = Immutable.List(
['ironMan', 'captainAmerica', 'blackWidow', 'theHulk']
);
const newAvengers = Immutable.List(
['scarletWitch', 'vision', 'antMan', 'falcon']
);
// Merge every other item
oldAvengers.mergeWith((oldAvenger, newAvenger, index) => {
return (index % 2) ? newAvenger : oldAvenger
}, newAvengers);
mergeDeep()
merge 做啥 mergeDeep 就干啥,但是對於嵌套列表,可以迭代線個層次中的項。
合並兩個嵌套列表,讓Immutable解決沖突
merge()使用相應索引處存在的合並List中的值覆蓋List中每個項目的值。但是,在嵌套列表的情況下,這可能會覆蓋整個嵌套List,而不是單個項目。
-- Demo
// Merge two nested Lists together with merge()
const oldAvengers = Immutable.fromJS(
[
['ironMan', ['captainAmerica']],
['theHulk', ['Thor']]
]);
const newAvengers = Immutable.fromJS(
[
['vision'],
[
['blackWidow']
]
]);
// This overwrites everything in oldAvengers
oldAvengers.merge(newAvengers);
** output: **
[["vision"], [["blackWidow"]]]
newAvengers List項目覆蓋oldAvengers中的所有相應項目(例如'vision'覆蓋'ironMan'和嵌套List'captainAmerica')。
要保留一個List的嵌套,並針對一個特定的嵌套級別,你需要使用mergeDeep:
// Merge two nested Lists together with mergeDeep()
const oldAvengers = Immutable.fromJS(
[
['ironMan', ['captainAmerica']],
['theHulk', ['Thor']]
]);
const newAvengers = Immutable.fromJS(
[
['vision'],
[
['blackWidow']
]
]);
// This leaves the nested Lists intact
oldAvengers.mergeDeep(newAvengers);
OUTPUT *********************************************************
[["vision", ["captainAmerica"]], [["blackWidow"], ["Thor"]]]
mergeDeepWith()
如果您需要自行決定應該合並哪個嵌套項目,請使用mergeDeepWtih:
將兩個嵌套列表合並在一起,自己解決沖突
list1.mergeDeepWith(conflictResolutionFn(list1Value, list2Value, index){}, list2)
// Merge two nested Lists together with mergeDeepWith()
const oldAvengers = Immutable.fromJS(
[
['ironMan', ['captainAmerica']],
['theHulk', ['Thor']]
]);
const newAvengers = Immutable.fromJS(
[
['vision'],
['blackWidow', 'Loki']
]);
// Loki can't replace Thor
oldAvengers.mergeDeepWith((prev, next, index) => {
return (next === 'Loki') ? prev : next
}, newAvengers);
OUTPUT ************************************************************
[["vision", ["captainAmerica"]], ["blackWidow", ["Thor"]]]
合並可能會非常棘手,有時候會讓你頭腦發熱,尤其是對於深度嵌套的列表。但是,使用自己的沖突解決功能的能力為操縱數據提供了強大的機制。