【譯】Immutable.js : 合並Map 7


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"}
        }
    }
}}


免責聲明!

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



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