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

array of objects group them by a specific key

I have the following array

const arr = [{
  agrupacion: "Total país",
  valor: "81.8",
  year: 2015
}, {
  agrupacion: "Total país",
  valor: "86.4",
  year: 2016
}, {
  agrupacion: "Total país",
  valor: "67.3",
  year: 2017
}, {
  agrupacion: "Total país",
  valor: "70.8",
  year: 2018
}, {
  agrupacion: "Total país",
  valor: "67.6",
  year: 2019
}, {
  agrupacion: "Oriental",
  valor: "78.6",
  year: 2015
}, {
  agrupacion: "Oriental",
  valor: "83.1",
  year: 2016
}, {
  agrupacion: "Oriental",
  valor: "65.6",
  year: 2017
}, {
  agrupacion: "Oriental",
  valor: "68.1",
  year: 2018
}, {
  agrupacion: "Oriental",
  valor: "63.7",
  year: 2019
}, {
  agrupacion: "Occidental",
  valor: "177.3",
  year: 2015
}, {
  agrupacion: "Occidental",
  valor: "182.9",
  year: 2016
}, {
  agrupacion: "Occidental",
  valor: "114.3",
  year: 2017
}, {
  agrupacion: "Occidental",
  valor: "144.5",
  year: 2018
}, {
  agrupacion: "Occidental",
  valor: "169.9",
  year: 2019
}, {
  agrupacion: "Urbano",
  valor: "79.6",
  year: 2015
}, {
  agrupacion: "Urbano",
  valor: "92.5",
  year: 2016
}, {
  agrupacion: "Urbano",
  valor: "62.1",
  year: 2017
}, {
  agrupacion: "Urbano",
  valor: "82.2",
  year: 2018
}, {
  agrupacion: "Urbano",
  valor: "80.6",
  year: 2019
}, {
  agrupacion: "Rural",
  valor: "86.5",
  year: 2015
}, {
  agrupacion: "Rural",
  valor: "63.7",
  year: 2016
}, {
  agrupacion: "Rural",
  valor: "87.2",
  year: 2017
}, {
  agrupacion: "Rural",
  valor: "45.7",
  year: 2018
}, {
  agrupacion: "Rural",
  valor: "38.9",
  year: 2019
}];

I used this method to achieve what I wanted:

const groups = new Map(arr.map(({agrupacion}) => [agrupacion, { agrupacion }]));
for (const {agrupacion, valor, year} of arr) {
    groups.get(agrupacion)["col" + year] = +valor;
}

const result = [...groups.values()];

the output is (console.log(result )):

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

[{
  agrupacion: "Total país",
  col2015: 81.8,
  col2016: 86.4,
  col2017: 67.3,
  col2018: 70.8,
  col2019: 67.6
}, {
  agrupacion: "Oriental",
  col2015: 78.6,
  col2016: 83.1,
  col2017: 65.6,
  col2018: 68.1,
  col2019: 63.7
}, {
  agrupacion: "Occidental",
  col2015: 177.3,
  col2016: 182.9,
  col2017: 114.3,
  col2018: 144.5,
  col2019: 169.9
}, {
  agrupacion: "Urbano",
  col2015: 79.6,
  col2016: 92.5,
  col2017: 62.1,
  col2018: 82.2,
  col2019: 80.6
}, {
  agrupacion: "Rural",
  col2015: 86.5,
  col2016: 63.7,
  col2017: 87.2,
  col2018: 45.7,
  col2019: 38.9
}];

That output is the format I need however the problem comes when I add additional data with the same "agrupacion" value to my arr array, for example I add this at the end of my arr array

,{
  agrupacion: "Total país",
  valor: "151",
  year: 2015
}, {
  agrupacion: "Total país",
  valor: "184",
  year: 2016
}, {
  agrupacion: "Total país",
  valor: "165",
  year: 2017
}, {
  agrupacion: "Total país",
  valor: "147",
  year: 2018
}, {
  agrupacion: "Total país",
  valor: "190",
  year: 2019
}

This is what I need:

[{
  agrupacion: "Total país",
  col2015: 81.8,
  col2016: 86.4,
  col2017: 67.3,
  col2018: 70.8,
  col2019: 67.6
}, {
  agrupacion: "Oriental",
  col2015: 78.6,
  col2016: 83.1,
  col2017: 65.6,
  col2018: 68.1,
  col2019: 63.7
}, {
  agrupacion: "Occidental",
  col2015: 177.3,
  col2016: 182.9,
  col2017: 114.3,
  col2018: 144.5,
  col2019: 169.9
}, {
  agrupacion: "Urbano",
  col2015: 79.6,
  col2016: 92.5,
  col2017: 62.1,
  col2018: 82.2,
  col2019: 80.6
}, {
  agrupacion: "Rural",
  col2015: 86.5,
  col2016: 63.7,
  col2017: 87.2,
  col2018: 45.7,
  col2019: 38.9
},{
  agrupacion: "Total país",
  col2015: 151,
  col2016: 184,
  col2017: 165,
  col2018: 147,
  col2019: 190
}];

This is what I get with my attempt:

[{
  agrupacion: "Total país",
  col2015: 151,
  col2016: 184,
  col2017: 165,
  col2018: 147,
  col2019: 190
}, {
  agrupacion: "Oriental",
  col2015: 78.6,
  col2016: 83.1,
  col2017: 65.6,
  col2018: 68.1,
  col2019: 63.7
}, {
  agrupacion: "Occidental",
  col2015: 177.3,
  col2016: 182.9,
  col2017: 114.3,
  col2018: 144.5,
  col2019: 169.9
}, {
  agrupacion: "Urbano",
  col2015: 79.6,
  col2016: 92.5,
  col2017: 62.1,
  col2018: 82.2,
  col2019: 80.6
}, {
  agrupacion: "Rural",
  col2015: 86.5,
  col2016: 63.7,
  col2017: 87.2,
  col2018: 45.7,
  col2019: 38.9
}]

Apparently it overwrites all the values from the first "Total país" rather than repeating that agrupacion with the new values that I added

>Solution :

Reduce the array into an object where the keys correspond to the agrupacion and the values correspond to an array of objects. And the length of this array is decided based on how many times an year appears for a particular agrupacion.

So, the following array:

[
  { agrupacion: "Total país", valor: "81.8", year: 2015 },
  { agrupacion: "Total país", valor: "86.4", year: 2016 },
  { agrupacion: "Total país", valor: "67.3", year: 2015 },
  { agrupacion: "Oriental", valor: "78.6", year: 2015 },
]

Is reduced into the following object:

{
  "Total país": [
    { agrupacion: "Total país", col2015: 81.8, col2016: 86.4 },
    { agrupacion: "Total país", col2015: 67.3 },
  ],
  Oriental: [{ agrupacion: "Oriental", col2015: 78.6 }],
}

And finally we get the values of this object and flatten it to the desired result.

const arr = [
  { agrupacion: "Total país", valor: "81.8", year: 2015 },
  { agrupacion: "Total país", valor: "86.4", year: 2016 },
  { agrupacion: "Total país", valor: "67.3", year: 2017 },
  { agrupacion: "Total país", valor: "70.8", year: 2018 },
  { agrupacion: "Total país", valor: "67.6", year: 2019 },
  { agrupacion: "Oriental", valor: "78.6", year: 2015 },
  { agrupacion: "Oriental", valor: "83.1", year: 2016 },
  { agrupacion: "Oriental", valor: "65.6", year: 2017 },
  { agrupacion: "Oriental", valor: "68.1", year: 2018 },
  { agrupacion: "Oriental", valor: "63.7", year: 2019 },
  { agrupacion: "Occidental", valor: "177.3", year: 2015 },
  { agrupacion: "Occidental", valor: "182.9", year: 2016 },
  { agrupacion: "Occidental", valor: "114.3", year: 2017 },
  { agrupacion: "Occidental", valor: "144.5", year: 2018 },
  { agrupacion: "Occidental", valor: "169.9", year: 2019 },
  { agrupacion: "Urbano", valor: "79.6", year: 2015 },
  { agrupacion: "Urbano", valor: "92.5", year: 2016 },
  { agrupacion: "Urbano", valor: "62.1", year: 2017 },
  { agrupacion: "Urbano", valor: "82.2", year: 2018 },
  { agrupacion: "Urbano", valor: "80.6", year: 2019 },
  { agrupacion: "Rural", valor: "86.5", year: 2015 },
  { agrupacion: "Rural", valor: "63.7", year: 2016 },
  { agrupacion: "Rural", valor: "87.2", year: 2017 },
  { agrupacion: "Rural", valor: "45.7", year: 2018 },
  { agrupacion: "Rural", valor: "38.9", year: 2019 },
  { agrupacion: "Total país", valor: "151", year: 2015 },
  { agrupacion: "Total país", valor: "184", year: 2016 },
  { agrupacion: "Total país", valor: "165", year: 2017 },
  { agrupacion: "Total país", valor: "147", year: 2018 },
  { agrupacion: "Total país", valor: "190", year: 2019 },
];

const result = Object.values(
  arr.reduce((r, o) => {
    if (!r[o.agrupacion]) {
      r[o.agrupacion] = [{ agrupacion: o.agrupacion }];
    }
    const item = r[o.agrupacion].find((i) => !i["col" + o.year]);
    if (item) {
      item["col" + o.year] = parseFloat(o.valor);
    } else {
      r[o.agrupacion].push({
        agrupacion: o.agrupacion,
        ["col" + o.year]: parseFloat(o.valor),
      });
    }
    return r;
  }, {})
).flat();

console.log(result);
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