Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Grouping an array by multiple keys with Array.reduce()

I am writing here for the first time, and I was given the following problem. For example, I have the following array:

const input = [
  {
    id: 1,
    date: "01-01-2021",
    source: "TT",
    metrics: { conversions: 10, cpl: 3 },
  },
  {
    id: 2,
    date: "01-01-2021",
    source: "TT",
    metrics: { conversions: 15, cpl: 3 },
  },
  {
    id: 3,
    date: "01-01-2021",
    source: "FB",
    metrics: { conversions: 15, cpl: 4 },
  },
  {
    id: 4,
    date: "01-01-2021",
    source: "FB",
    metrics: { conversions: 15, cpl: 4 },
  },
  {
    id: 5,
    date: "02-01-2021",
    source: "TT",
    metrics: { conversions: 5, cpl: 2 },
  },
  {
    id: 6,
    date: "02-01-2021",
    source: "TT",
    metrics: { conversions: 15, cpl: 2 },
  },
  {
    id: 7,
    date: "02-01-2021",
    source: "FB",
    metrics: { conversions: 25, cpl: 1 },
  },
  {
    id: 8,
    date: "02-01-2021",
    source: "FB",
    metrics: { conversions: 30, cpl: 1 },
  },
];

And I need to get an array grouped by date and source and the value will be the sum of all its values ​​for a specific date, for example as the result below:

const output = [
  {
    date: "01-01-2021",
    TT: 25,
    FB: 30,
  },
  {
    date: "02-01-2021",
    TT: 20,
    FB: 55,
  },
];

In my solution, I find unique keys and dates, but do not understand what to do next. Can you help me? Sample code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const result = input.reduce((acc, current) => {
  const dateItem = acc.find((item) => item.date === current.date);
  const sources = input.map((item) => item.source).filter((value, index, self) => self.indexOf(value) === index);

  if (dateItem) {
    return [...acc.filter((i) => i.date !== current.date), { ...dateItem }];
  }

  return [...acc, { date: current.date }];
}, []);

>Solution :

Simple reduce loop using the date as a key. After you get it all combined, you can use values to get the array.

const input = [{
    id: 1,
    date: "01-01-2021",
    source: "TT",
    metrics: {
      conversions: 10,
      cpl: 3
    },
  },
  {
    id: 2,
    date: "01-01-2021",
    source: "TT",
    metrics: {
      conversions: 15,
      cpl: 3
    },
  },
  {
    id: 3,
    date: "01-01-2021",
    source: "FB",
    metrics: {
      conversions: 15,
      cpl: 4
    },
  },
  {
    id: 4,
    date: "01-01-2021",
    source: "FB",
    metrics: {
      conversions: 15,
      cpl: 4
    },
  },
  {
    id: 5,
    date: "02-01-2021",
    source: "TT",
    metrics: {
      conversions: 5,
      cpl: 2
    },
  },
  {
    id: 6,
    date: "02-01-2021",
    source: "TT",
    metrics: {
      conversions: 15,
      cpl: 2
    },
  },
  {
    id: 7,
    date: "02-01-2021",
    source: "FB",
    metrics: {
      conversions: 25,
      cpl: 1
    },
  },
  {
    id: 8,
    date: "02-01-2021",
    source: "FB",
    metrics: {
      conversions: 30,
      cpl: 1
    },
  },
];


const results = Object.values(input.reduce((o, data) => {
  o[data.date] = o[data.date] || { date: data.date };
  o[data.date][data.source] = (o[data.date][data.source] || 0) + data.metrics.conversions;
  return o;
}, {}));
console.log(results);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading