0

Multiple objects i have with common keys, am trying to group all duplicated objects and map any extra key exist in any object

Data i have like below

var array = [
  { id: 'Staging', cumulative: 16 },
  { id: 'Staging', yeasterday: 16 },
  { id: 'Staging', week: 16 },
  { id: 'Staging', yeasterday: 16 },

  { id: 'Staging1', cumulative: 16 },
  { id: 'Staging1', yeasterday: 16 },
  { id: 'Staging1', week: 16 },
];

Expected results, suppose to be below

var array = [
  { id: 'Staging', cumulative: 16, month: 16, week: 16, yeasterday: 16 },

  { id: 'Staging1', cumulative: 16, yeasterday: 16, week: 16 },
];

Sam
  • 111
  • 1
  • 11
  • 3
    Please, take a read to [how to ask](https://stackoverflow.com/help/how-to-ask). It will be nice to see what you have tried and the expected output. – Shidersz Apr 22 '19 at 05:40
  • simple google search https://www.google.com/search?q=group+by+javascript&oq=group+by+javascript&aqs=chrome..69i57j0l5.4591j0j4&sourceid=chrome&ie=UTF-8 will give you the answer. – Junius L Apr 22 '19 at 05:53
  • Possible duplicate of [Most efficient method to groupby on a array of objects](https://stackoverflow.com/questions/14446511/most-efficient-method-to-groupby-on-a-array-of-objects) – Junius L Apr 22 '19 at 05:55
  • Why is `yeasterday ` repeated twice for the first object of the result array? – wentjun Apr 22 '19 at 05:59

3 Answers3

1

Use reduce like so:

var array = [{
  id: "Staging",
  cumulative: 16
}, {
  id: "Staging",
  yeasterday: 16
}, {
  id: "Staging",
  week: 16
}, {
  id: "Staging",
  yeasterday: 16
}, {
  id: "Staging1",
  cumulative: 16
}, {
  id: "Staging1",
  yeasterday: 16
}, {
  id: "Staging1",
  week: 16
}]

var newArray = array.reduce((acc, { id, ...rest }) => {
  acc[id] = { ...(acc[id] || {}), ...rest };
  return acc;
}, {});

console.log(newArray);
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
0

You can achieve this by with Vanilla JavaScript (without any clunky external libraries such as Lodash). My approach will require you to use Array.reduce(), together with Map which is one of ES6's features. Then, we can use the spread syntax (or Array.from()) to transform the Iterator object (which contains the values of each element from the Map object) into an array to obtain the format similar to the required output as stated on the question.

const arr = [ {id: "Staging", cumulative: 16}, {id: "Staging", yeasterday: 16}, {id: "Staging", week: 16}, {id: "Staging", yeasterday: 16},
{id: "Staging1", cumulative: 16}, {id: "Staging1", yeasterday: 16}, {id: "Staging1", week: 16}
]

const iteratorMap = arr.reduce((entry, e) => entry.set(e['id'], {...entry.get(e['id'])||{}, ...e}), new Map()).values();

const result = [...iteratorMap];

console.log(result);
wentjun
  • 40,384
  • 10
  • 95
  • 107
0

You can easily use lodash library and obtain the resutls

var result = _.chain(array)
              .groupBy('id')
              .map((val) => _.reduce(val, (result, value) => _.merge(result, value), {}))
              .value()
Meuru
  • 66
  • 1
  • 4