【譯】Immutable.js: 合並 List - 4


在之前的文章中,我們已經看到了如何創建一個新的列表,以及如何添加,插入和刪除項目。現在是時候學習更高級一點的技能了 —— 合並兩個或更多列表的方式。

注意:記住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"]]]

合並可能會非常棘手,有時候會讓你頭腦發熱,尤其是對於深度嵌套的列表。但是,使用自己的沖突解決功能的能力為操縱數據提供了強大的機制。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM