3

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?

2 Answers 2

2

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)

Sign up to request clarification or add additional context in comments.

Comments

0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.