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 )):
[{
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);