【问题标题】:Lodash union of arrays of objects对象数组的 Lodash 联合
【发布时间】:2015-06-01 23:16:15
【问题描述】:

我想使用_.union 函数来创建两个对象数组的联合。 Union 仅适用于基元数组,因为它使用 === 检查两个值是否相等。

我想使用键属性比较对象:具有相同键属性的对象将被视为相等。有没有一种很好的功能性方法可以理想地使用 lodash 实现这一目标?

【问题讨论】:

    标签: javascript lodash


    【解决方案1】:

    一种非纯 lodash 的方式来做到这一点,但使用 array.concat 函数你可以很简单地沿着 uniq() 做到这一点:

    var objUnion = function(array1, array2, matcher) {
      var concated = array1.concat(array2)
      return _.uniq(concated, false, matcher);
    }
    

    另一种方法是使用flatten()uniq()

    var union = _.uniq(_.flatten([array1, array2]), matcherFn);
    

    【讨论】:

    • 什么是 matcherFn 或 matcher?
    • matcherFn/matcher 只是我所说的你编写的用于确定对象是否唯一的函数
    【解决方案2】:

    那么UniqBy 之前有两个数组的连接呢?

    import _ from 'lodash'
    
    const arrayUnion = (arr1, arr2, identifier) => {
      const array = [...arr1, ...arr2]
    
      return _.uniqBy(array, identifier)  
     }
    
    
    const array1 = [{ id: 1 }, { id: 2 }, { id: 3 }]
    const array2 = [{ id: 3 }, { id: 4 }, { id: 4 }]
    
    console.log(arrayUnion(array1, array2, 'id'))
    

    结果 → [{ 'id': 1 }, { 'id': 2 }, { 'id': 3 }, { 'id': 4 }]

    【讨论】:

    • 我在这里看不到两个数组正在合并。
    • @SirajAlam 合并在这里完成: const array = [...arr1, ...arr2]
    【解决方案3】:

    _.unionBy(array1, array2, matcherFn);

    【讨论】:

      【解决方案4】:

      lodash 从数组中合并对象

      const test1 = [
        { name: 'zhanghong', age: 32, money: 0, size: 12, },
        { name: 'wanghong', age: 20, size: 6 },
        { name: 'jinhong', age: 16, height: 172 },
      ]
      
      const test2 = [
        { name: 'zhanghong', gender: 'male', age: 14 },
        { name: 'wanghong', gender: 'female', age: 33 },
        { name: 'lihong', gender: 'female', age: 33 },
      ]
      
      const test3 = [
        { name: 'meinv' },
      ]
      
      const test4 = [
        { name: 'aaa' },
      ]
      
      const test5 = [
        { name: 'zhanghong', age: 'wtf' },
      ]
      
      const result = mergeUnionByKey(test1, test2, test3, test4, [], test5, 'name', 'override')
      
      function mergeUnionByKey(...args) {
      
        const config = _.chain(args)
          .filter(_.isString)
          .value()
      
        const key = _.get(config, '[0]')
      
        const strategy = _.get(config, '[1]') === 'override' ? _.merge : _.defaultsDeep
      
        if (!_.isString(key))
          throw new Error('missing key')
      
        const datasets = _.chain(args)
          .reject(_.isEmpty)
          .filter(_.isArray)
          .value()
      
        const datasetsIndex = _.mapValues(datasets, dataset => _.keyBy(dataset, key))
      
        const uniqKeys = _.chain(datasets)
          .flatten()
          .map(key)
          .uniq()
          .value()
      
        return _.chain(uniqKeys)
          .map(val => {
            const data = {}
            _.each(datasetsIndex, dataset => strategy(data, dataset[val]))
            return data
          })
          .filter(key)
          .value()
      
      }
      
      console.log(JSON.stringify(result, null, 4))
      <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

      【讨论】:

      • 谢谢 :) 你为我节省了不少时间。我真的不想写这个函数lol
      【解决方案5】:

      聚会迟到了,但 _.unionWith 做你想做的事要好得多。

      var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
      var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
      
      _.unionWith(objects, others, _.isEqual);
      // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
      

      【讨论】:

        【解决方案6】:
        1. 使用关键属性比较对象:-

        _.unionBy(array1,array2,'propname');

        1. 使用所有关键属性比较对象:-

        _.unionWith(array1,array2, _.isEqual);

        1. 以不区分大小写的方式使用字符串键属性比较对象:-

        _.unionWith(array1,array2, function(obj,other){ return obj.propname.toLowercase() === other.propname.toLowercase(); });

        propname 是您的对象的关键属性的名称。

        【讨论】:

          【解决方案7】:

          _.spread(_.merge) 可以解决问题。

          _.spread(_.merge)([{ a: 1 }, { b: 2 }, { c: 3 }])
          

          会返回 { a: 1, b: 2, c: 3 }

          【讨论】:

            猜你喜欢
            • 2017-02-22
            • 1970-01-01
            • 2016-06-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-05-07
            • 2015-07-07
            • 1970-01-01
            相关资源
            最近更新 更多