Search code examples
javascriptlodash

Union objects by equal properties and concatenating by different ones in the same array


I get this array and want to join objects when the values of code, name, document and value are all equals and concatenate months and hours. I tried to use lodash without success.

Is there a way to do this using lodash? I tried to use groupBy with unionBy without success .. the results are messy arrays. Thank you.

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

This is the expected result:

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

Solution

  • Group by the keys using _.groupBy(), and then use _.map() to merge the items of each group with _.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>