web-dev-qa-db-fra.com

Union de Lodash de tableaux d'objets

J'aimerais utiliser le _.union fonction pour créer une union de deux tableaux d'objets. Union ne fonctionne avec des tableaux de primitives que dans la mesure où elle utilise === pour examiner si deux valeurs sont égales.

Je voudrais comparer des objets en utilisant une propriété de clé: les objets avec la même propriété de clé seraient considérés comme égaux. Existe-t-il une belle façon fonctionnelle de réaliser cela idéalement en utilisant lodash?

14
Janos

Une manière non pure de lodash pour le faire, mais en utilisant la fonction array.concat, vous pouvez le faire assez simplement le long de uniq():

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

Une autre approche consisterait à utiliser flatten () et niq () :

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

Et qu'en est-il de niqBy avec un concaténage des deux tableaux avant?

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

résultat → [{'x': 1}, {'x': 2}]

13
MatthieuH

En retard à la fête, mais _.unionWith est beaucoup mieux pour faire ce que vous voulez.

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

_.unionBy(array1, array2, matcherFn);

2
olegzhermal

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>
2
crapthings
  1. Comparez les objets à l'aide d'une propriété de clé: -

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

  1. Comparez les objets en utilisant toutes les propriétés de clé: -

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

  1. Comparez les objets en utilisant une propriété de clé de chaîne de manière insensible à la casse: -

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

propname est le nom de la propriété clé de votre objet.

0
Pravin Divraniya