Here’s a sample of a very particular dataset I am working on. I have an array of objects in the following format:
const input = [
{year: "2010", country_id: "01", country: "India", region: "North", category: "a", value: "10", population: "100"},
{year: "2010", country_id: "01", country: "India", region: "South", category: "a", value: "10", population: "100"},
{year: "2010", country_id: "01", country: "India", region: "North", category: "b", value: "10", population: "100"},
{year: "2010", country_id: "01", country: "India", region: "North", category: "c", value: "10", population: "100"},
{year: "2015", country_id: "01", country: "India", region: "South", category: "a", value: "10", population: "100"},
{year: "2015", country_id: "01", country: "India", region: "South", category: "a", value: "10", population: "100"},
{year: "2015", country_id: "01", country: "India", region: "North", category: "b", value: "10", population: "100"},
{year: "2015", country_id: "01", country: "India", region: "North", category: "c", value: "10", population: "100"},
{year: "2015", country_id: "01", country: "India", region: "East", category: "c", value: "10", population: "100"},
{year: "2015", country_id: "02", country: "Turkey", region: "North", category: "a", value: "15", population: "25"},
{year: "2015", country_id: "02", country: "Turkey", region: "North", category: "b", value: "5", population: "25"}
]
How can I collapse the objects in the array based on year
and id
and create a
, b
, c
and total_population
new properties in output based on the data in category
, value
and population
from input?
One thing to note is that a
, b
and c
are cumulative sums and total_population
is a cumulative sum based on region
. This means that population
values are duplicated i some cases (i.e.: there are three entries in country “India” and region “North” that should total 100 and not 300.)
const output = [
{year: "2010", id: "01", country: "India", a: 20, b: 10, c: 10, total_population: 200},
{year: "2015", id: "01", country: "India", a: 10, b: 10, c: 20, population: 300},
{year: "2015", id: "02", country: "Turkey", a: 15, b: 5, population: 25}
]
My best attempt follows. Unfortunately I am constantly getting NaN when trying to execute the cumulative sum. Also, it seems that this solution does not perform well when testing it in a larger dataset.
const years = [...new Set(input.map((d) => d.year))].sort()
const country_ids = [...new Set(input.map((d) => d.country_id))].sort()
const combined_ids = {
let array = [];
country_ids.forEach((y, i) => {
years.forEach((m) => {
let obj = {};
obj["year"] = m;
obj["country_id"] = y;
obj["combined_id"] = m + "-" + y;
array.push(obj);
});
});
return array;
}
const output = combined_ids.map((y, i) => {
input.map((m) => {
if (y.combined_id === m.year + "-" + m.country_id) {
y.country_id = m.country_id;
y[m.category] += !m.category
? 0
: m.value === NaN
? 0
: m.value === null
? 0
: m.value === undefined
? 0
: m.category === undefined
? 0
: +m.value;
y["total_population"] += +m.population;
}
});
return y;
});