Reputation: 211
I have:
[{ID: "1", Job: "Student", Gender: "Male", Income: 2200},
{ID: "2", Job: "Student", Gender: "Male", Income: 1300},
{ID: "3", Job: "Student", Gender: "Female", Income: 5400},
{ID: "4", Job: "Teacher", Gender: "Female", Income: 4200},
{ID: "5", Job: "Teacher", Gender: "Female", Income: 4000}]
Trying to manipulate into the below format for d3 stacked bar chart (like the data in this link) :
[{name: "Student", Male: 3500, Female: 5400},
{name: "Teacher", Male: 0, Female: 8200}]
I tried all sorts of for-loop and sums and got myself all confused, so I won't bore you with my lengthy inefficient code. How would you do it?
Upvotes: 3
Views: 83
Reputation: 3371
I would probably do it like this for my own code. One concern might be that the get_totals_by_job function is a bit difficult to understand without some effort.
const data = [{ID: "1", Job: "Student", Gender: "Male", Income: 2200},
{ID: "2", Job: "Student", Gender: "Male", Income: 1300},
{ID: "3", Job: "Student", Gender: "Female", Income: 5400},
{ID: "4", Job: "Teacher", Gender: "Female", Income: 4200},
{ID: "5", Job: "Teacher", Gender: "Female", Income: 4000}];
const get_totals_by_job = (acc, val) => Object.assign(
acc,
{
[val.Job]: Object.assign(
acc[val.Job] || { Male: 0, Female: 0 },
{ [val.Gender]: (acc[val.Job]?.[val.Gender] || 0) + val.Income }
)
}
);
const result = Object
.entries( data.reduce(get_totals_by_job, {}) )
.map( ([name, totals]) => Object.assign({ name }, totals) );
console.log(result);
Upvotes: 0
Reputation: 18036
You can use reduce for that.
The reduce method executes a reducer function on each element of the array. the reducer function's returned value is assigned to the accumulator (res). this value is remembered for each iteration throughout the array. the second value is the current value which we will use to figure out is this a Male/Female and add to the relatively gender income.
const data = [{ID: "1", Job: "Student", Gender: "Male", Income: 2200},
{ID: "2", Job: "Student", Gender: "Male", Income: 1300},
{ID: "3", Job: "Student", Gender: "Female", Income: 5400},
{ID: "4", Job: "Teacher", Gender: "Female", Income: 4200},
{ID: "5", Job: "Teacher", Gender: "Female", Income: 4000}];
var result = [];
data.reduce(function(res, value) {
if (!res[value.Job]) {
res[value.Job] = { name: value.Job, Male: 0, Female: 0 };
result.push(res[value.Job])
}
if (value.Gender === "Male"){
res[value.Job].Male += value.Income;
}
else{
res[value.Job].Female += value.Income;
}
return res;
}, {});
console.log(result)
Upvotes: 2