Lodash union of arrays of objects

╄→гoц情女王★ 提交于 2019-12-18 14:48:22

问题


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 values are equal.

I'd like to compare objects using a key property: objects with the same key property would be regarded equal. Is there a nice functional way to achieve that ideally using lodash?


回答1:


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



回答2:


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

_.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');

result → [{ 'x': 1 }, { 'x': 2 }]




回答3:


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



回答4:


_.unionBy(array1, array2, matcherFn);




回答5:


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>



回答6:


  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.



来源:https://stackoverflow.com/questions/29320817/lodash-union-of-arrays-of-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!