【问题标题】:Deep Merge using Lodash使用 Lodash 进行深度合并
【发布时间】:2017-01-07 20:05:23
【问题描述】:

我有两个对象数组,其中包含具有标签的地址和实际地址的对象:

var originalAddresses = [
  {
    label: 'home',
    address: { city: 'London', zipCode: '12345' }
  },
  {
    label: 'work',
    address: { city: 'New York', zipCode: '54321' }
  }
];

var updatedAddresses = [
  {
    label: 'home',
    address: { city: 'London (Central)', country: 'UK' }
  },
  {
    label: 'spain',
    address: { city: 'Madrid', zipCode: '55555' }
  }
];

现在我想通过label 合并这些数组并比较地址的各个属性并仅合并新地址中实际存在的属性。所以结果应该是这样的:

var result = [
  {
    label: 'home',
    address: { city: 'London (Central)', zipCode: '12345', country: 'UK' }
  },
  {
    label: 'work',
    address: { city: 'New York', zipCode: '54321' }
  },
  {
    label: 'spain',
    address: { city: 'Madrid', zipCode: '55555' }
  }
]

如何使用lodash 来做到这一点? 我尝试了unionBy()merge() 的组合。使用 unionBy() 我可以按标签比较和连接数组,但这总是会替换整个对象。我可以确定合并地址,但这不会按标签发生。

【问题讨论】:

    标签: javascript arrays merge lodash


    【解决方案1】:

    您可以使用_.keyBy(arr, 'label') 将两个数组转换为对象,然后使用_.merge() 进行深度合并:

    var originalAddresses = [{
      label: 'home',
      address: {
        city: 'London',
        zipCode: '12345'
      }
    }, {
      label: 'work',
      address: {
        city: 'New York',
        zipCode: '54321'
      }
    }];
    
    var updatedAddresses = [{
      label: 'home',
      address: {
        city: 'London (Central)',
        country: 'UK'
      }
    }, {
      label: 'spain',
      address: {
        city: 'Madrid',
        zipCode: '55555'
      }
    }];
    
    var result = _.values(_.merge(
      _.keyBy(originalAddresses, 'label'),
      _.keyBy(updatedAddresses, 'label')
    ));
    
    console.log(result);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

    【讨论】:

      【解决方案2】:

      我尝试使用 VanillaJS 来处理这个问题。

      const originalAddresses = [{
          label: 'home',
          address: {
              city: 'London',
              zipCode: '12345'
          }
      }, {
          label: 'work',
          address: {
              city: 'New York',
              zipCode: '54321'
          }
      }];
      
      const updatedAddresses = [{
          label: 'home',
          address: {
              city: 'London (Central)',
              country: 'UK'
          }
      }, {
          label: 'spain',
          address: {
              city: 'Madrid',
              zipCode: '55555'
          }
      }];
      
      
      const groupBy = (array, property) => {
          return array.reduce((acc, cur) => {
                  let key = cur[property]
                  if (!acc[key]) {
                      acc[key] = []
                  }
                  acc[key].push(cur)
      
                  return acc
              }
              , {})
      }
      
      const groupByLabel = groupBy([...originalAddresses, ...updatedAddresses], 'label')
      
      const result  = Object.keys(groupByLabel).map((key) => {
              return {
                  label: groupByLabel[key][0].label,
                  address: groupByLabel[key].reduce((acc, cur) => {
                          return Object.assign(acc, cur.address)
                      }
                      , {})
              }
          }
      )
      console.log(result)
      
      

      【讨论】:

        【解决方案3】:

        您可以使用 _.keyBy(arr, 'label') 将两个数组转换为对象,然后使用 _.merge() 进行深度合并:

        var originalAddresses = [{
          label: 'home',
          address: {
            city: 'London',
            zipCode: '12345'
          }
        }, {
          label: 'work',
          address: {
            city: 'New York',
            zipCode: '54321'
          }
        }];
        
        var updatedAddresses = [{
          label: 'home',
          address: {
            city: 'London (Central)',
            country: 'UK'
          }
        }, {
          label: 'spain',
          address: {
            city: 'Madrid',
            zipCode: '55555'
          }
        }];
        
        var result = _.values(_.merge(
          _.keyBy(originalAddresses, 'label'),
          _.keyBy(updatedAddresses, 'label')
        ));
        
        console.log(result);
        

        【讨论】:

        • 不错...复制?
        猜你喜欢
        • 2016-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-26
        • 2016-09-01
        • 2015-10-19
        相关资源
        最近更新 更多