Lodash объединение массивов объектов

Я хотел бы использовать функцию _.union для создания объединения двух массивов объектов. Union работает только с массивами примитивов, так как использует === для проверки равенства двух значений.

Я хотел бы сравнить объекты с использованием ключевого свойства: объекты с одним и тем же ключевым свойством будут считаться равными. Есть ли хороший функциональный способ добиться этого в идеале с помощью lodash?


person Janos    schedule 28.03.2015    source источник


Ответы (5)


Не чистый способ 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);
person Craig Suchanec    schedule 28.03.2015
comment
что такое matcherFn или matcher? - person J Bourne; 13.11.2015
comment
matcherFn/matcher — это просто мой способ сказать, что функция, которую вы пишете, определяет уникальность объектов. - person Craig Suchanec; 20.02.2016

А как насчет 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}]

person MatthieuH    schedule 29.01.2016
comment
Я не вижу здесь двух объединенных массивов. - person Siraj Alam; 07.05.2020
comment
Слияние @SirajAlam выполняется здесь: const array = [...arr1, ...arr2] - person MatthieuH; 21.08.2020

Поздно на вечеринку, но _.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 }]
person alaboudi    schedule 24.04.2017

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>

person crapthings    schedule 20.01.2017
comment
Спасибо :) вы сэкономили мне немало времени. Я действительно не хотел писать эту функцию, лол - person James Harrington; 15.03.2020

  1. Сравните объекты, используя ключевое свойство: -

_.unionBy (массив1, массив2, 'имя свойства');

  1. Сравните объекты, используя все ключевые свойства: -

_.unionWith (массив1, массив2, _.isEqual);

  1. Сравните объекты, используя свойство строкового ключа в нечувствительном к регистру способе: -

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

propname — это имя ключевого свойства вашего объекта.

person Pravin Divraniya    schedule 28.11.2019