0

I have an array as follows:

const arr = [{
  name: 'XYZ',
  values: [1, 2, 3]
}, {
  name: 'ABC',
  values: [5]
}, {
  name: 'XYZ',
  values: [4, 5, 6]
}, {
  name: 'ABC',
  values: [8, 9]
}];

I'm using underscore js and trying to transform as follows:

const result = [{
  name: 'XYZ',
  values: [1, 2, 3, 4, 5, 6]
}, {
  name: 'ABC',
  values: [5, 8, 9]
}]

I was able to group by name and trying to loop in, but not sure how do I merge values. So far this is what I've done:

_.chain(arr)
  .groupBy((item) => item.name)
  // I don't know what to do here
  .value();

2 Answers 2

2

With ES6, you can use Array#reduce with a Map to get the desired result:

const arr = [{"name":"XYZ","values":[1,2,3]},{"name":"ABC","values":[5]},{"name":"XYZ","values":[4,5,6]},{"name":"ABC","values":[8,9]}];

const result = [...arr.reduce((m, { name, values }) => {
  const el = m.get(name) || { name, values: [] }; // get the result object from the map or create a new one
  
  el.values.push(...values); // push the current values to the result object values property

  return m.set(name, el); // add the result object to the map, and return the map
}, new Map()).values()]; // get the map values, and spread to an array

console.log(result);

Using underscore:

const arr = [{"name":"XYZ","values":[1,2,3]},{"name":"ABC","values":[5]},{"name":"XYZ","values":[4,5,6]},{"name":"ABC","values":[8,9]}];

const result = _.chain(arr)
  .groupBy('name') // group by name
  .mapObject((group, name) => ({ // map each group to a new object
    name,
    values: _.flatten(_.pluck(group, 'values')) // get all values arrays, and flatten to a single array
  }))
  .values() // convert the groups object to an array
  .value();

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

Sign up to request clarification or add additional context in comments.

2 Comments

Great, I'm able to understand the underscore part. It would be great if you can explain the ES6 part.
See update. Note that to understand the ES6 solution, you'll have to read about Map, Array#reduce, and spread syntax.
0

Maybe, you can try vanilla Javascript way.

var result = [];
arr.forEach((item) => {
    let currObj = result.find((item2) => item2.name === item.name);
    if(currObj){
      currObj.values = currObj.values.concat(item.values);
    } else {
      result.push(JSON.parse(JSON.stringify(item)));
    }
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.