Lodash union of arrays of objects

前端 未结 6 1680
臣服心动
臣服心动 2020-12-10 02:57

I\'d like to use the _.union function to create a union of two arrays of objects. Union works with arrays of primitives only as it uses === to examine if two va

相关标签:
6条回答
  • 2020-12-10 03:30
    1. Compare objects using a key property:-

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

    1. Compare objects using all key property:-

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

    1. Compare objects using a string key property in case insensitive way:-

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

    propname is name of key property of your object.

    0 讨论(0)
  • 2020-12-10 03:40

    And what about UniqBy with a concat of the two arrays before?

    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'))
    

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

    0 讨论(0)
  • 2020-12-10 03:47

    lodash merge object from arrays

    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>

    0 讨论(0)
  • 2020-12-10 03:48

    _.unionBy(array1, array2, matcherFn);

    0 讨论(0)
  • 2020-12-10 03:52

    A non pure lodash way to do this but using the array.concat function you are able to do this pretty simply along uniq():

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

    An alternative approach would be to use flatten() and uniq():

    var union = _.uniq(_.flatten([array1, array2]), matcherFn);
    
    0 讨论(0)
  • 2020-12-10 03:55

    Late to the party but _.unionWith is much better in doing what you want.

    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 }]
    
    0 讨论(0)
提交回复
热议问题