Объединяет объекты с одинаковыми свойствами и объединяет разные объекты в одном массиве. - PullRequest
0 голосов
/ 14 декабря 2018

Я получаю этот массив и хочу объединить объекты, когда значения кода, имени, документа и значения равны и объединяют месяцы и часы.Я безуспешно пытался использовать lodash.

Есть ли способ сделать это с помощью lodash?Я попытался использовать groupBy с unionBy, но безуспешно .. результаты - грязные массивы.Спасибо.

    const arrayOfObject = [
    {
      code: '6666',
      name: 'Foo Bar',
      doc: '60170150166',
      value: '158.56',
      month: '082011',
      hours: '20'
    },
    {
      code: '6666',
      name: 'Foo Bar',
      doc: '60170150166',
      value: '158.56',
      month: '092011',
      hours: '20'
    },
    {
      code: '6666',
      name: 'Foo Bar',
      doc: '60170150166',
      value: '158.56',
      month: '102011',
      hours: '10'
    },
    {
      code: '6666',
      name: 'Foo Bar',
      doc: '60170150166',
      value: '169.81',
      month: '042012',
      hours: '10'
    },
    {
      code: '6666',
      name: 'Foo Bar',
      doc: '60170150166',
      value: '169.81',
      month: '052012',
      hours: '10'
    }
  ];

Это ожидаемый результат:

const expectedArray = [
    {
      code: '6666',
      name: 'Foo Bar',
      doc: '60170150166',
      value: '158.56',
      month: '082011, 092011, 102011',
      hours: '20, 20, 10'
    },
    {
      code: '6666',
      name: 'Foo Bar',
      doc: '60170150166',
      value: '169.81',
      month: '042012, 052012',
      hours: '10, 10'
    }
  ];

Ответы [ 3 ]

0 голосов
/ 14 декабря 2018

Просто используйте _. UnionBy

let groupedObject = _.unionBy(arrayOfObject, (element) => {
  return (element.code && element.name && element.doc && element.value)
})

рабочая скрипка: https://jsfiddle.net/oqtLpbxr/

И, как упомянул TJ Crowder в комментариях, было бы неплохо, если бы выпо крайней мере, ПОПРОБУЙТЕ сделать это самостоятельно и опубликовать код.

0 голосов
/ 14 декабря 2018

Использование собственного Array#reduce() для создания группового объекта и затем Object.values() для возврата результирующего массива.

Для меня это легче читать, чем объединение нескольких методов lodash

Примечание Я изменилhours и month` для массивов, поскольку это, как правило, более полезно, чем string ... настроить при необходимости

const grouped = Object.values(
    arrayOfObject.reduce((a,c)=>{
       const key = [c.code, c.name, c.doc, c.value].join('|');
       a[key] = a[key] || Object.assign({}, c, {month:[],hours:[]});
       a[key].month.push(c.month)
       a[key].hours.push(c.hours);
       return a
    },{})
);

console.log(grouped)
<script>
  const arrayOfObject = [
    {
      code: '6666',
      name: 'Foo Bar',
      doc: '60170150166',
      value: '158.56',
      month: '082011',
      hours: '20'
    },
    {
      code: '6666',
      name: 'Foo Bar',
      doc: '60170150166',
      value: '158.56',
      month: '092011',
      hours: '20'
    },
    {
      code: '6666',
      name: 'Foo Bar',
      doc: '60170150166',
      value: '158.56',
      month: '102011',
      hours: '10'
    },
    {
      code: '6666',
      name: 'Foo Bar',
      doc: '60170150166',
      value: '169.81',
      month: '042012',
      hours: '10'
    },
    {
      code: '6666',
      name: 'Foo Bar',
      doc: '60170150166',
      value: '169.81',
      month: '052012',
      hours: '10'
    }
  ];
</script>
0 голосов
/ 14 декабря 2018

Группируйте по ключам, используя _.groupBy(), а затем используйте _.map(), чтобы объединить элементы каждой группы с _.mergeWith():

const combine = _.flow([
  arr => _.groupBy(arr, o => [o.code, o.name, o.document, o.value].join('-')),
  groups => _.map(groups, g => _.mergeWith(...g, (o, s, k) => {
    if(k === 'month' || k === 'hours') return `${o}, ${s}`;
  }))
]);

 const arrayOfObject = [{"code":"6666","name":"Foo Bar","doc":"60170150166","value":"158.56","month":"082011","hours":"20"},{"code":"6666","name":"Foo Bar","doc":"60170150166","value":"158.56","month":"092011","hours":"20"},{"code":"6666","name":"Foo Bar","doc":"60170150166","value":"158.56","month":"102011","hours":"10"},{"code":"6666","name":"Foo Bar","doc":"60170150166","value":"169.81","month":"042012","hours":"10"},{"code":"6666","name":"Foo Bar","doc":"60170150166","value":"169.81","month":"052012","hours":"10"}];
  
const result = combine(arrayOfObject);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
...