相关文章推荐
豁达的紫菜  ·  Tutor local do init ...·  1 年前    · 
玩命的小虾米  ·  和平精英机型适配 ...·  1 年前    · 
爱听歌的咖啡豆  ·  辽宁日报·  1 年前    · 

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