简体   繁体   中英

How to split an object into multiple objects based on data in one of it's values[unique values in an array]

I am looking to split the below data based on StudentID. I know that I have to compare each element in StudentID with every other element and push the data into a new object if we came across a new studentID,but I don't know how to implement this, as I am new to programming.

Input data:

data=[{"StudentID":["1","1","1","1","2","2","2","2","3","3","3","3","4","4","4","4"],
    "ModuleCode:"DES3095-N",
    "WeekNum":["1","2","3","4","1","2","3","4","1","2","3","4","1","2","3","4"],
    "Status":["p","p","pdg","p","abs","cc","p","abs","p","p","abs","p","p","abs","abs","abs"]}]

The output I am trying to achieve is:

[{"StudentID":1,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["p","p","pdg","p"]}
{"StudentID":2,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["abs","cc","p","abs"]}
{"StudentID":3,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["p","p","abs","p"]}
{"StudentID":4,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["p","abs","abs","abs"]}]

My ultimate aim here is to plot the average attendance of a student for a given Module, using D3.js. PS The original data set is much much bigger.

Ok, it is a bit of a strange data structure you have (data is a single object within an array - so it's not clear if this is always the case or if you expect multiple objects in that array) but let's see what we can do:

 const data = [ { "StudentID":["1","1","1","1","2","2","2","2","3","3","3","3","4","4","4","4"], "ModuleCode": "DES3095-N", "WeekNum":["1","2","3","4","1","2","3","4","1","2","3","4","1","2","3","4"], "Status":["p","p","pdg","p","abs","cc","p","abs","p","p","abs","p","p","abs","abs","abs"] }/*, { "StudentID":["1","1","1","1","2","2","2","2","3","3","3","3","4","4","4","4"], "ModuleCode": "DES4095-P", "WeekNum":["1","2","3","4","1","2","3","4","1","2","3","4","1","2","3","4"], "Status":["p","p","pdg","p","abs","cc","p","abs","p","p","abs","p","p","abs","abs","abs"] }*/ ]; /* The Goal output is: [{"StudentID":1,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["p","p","pdg","p"]}, {"StudentID":2,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["abs","cc","p","abs"]}, {"StudentID":3,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["p","p","abs","p"]}, {"StudentID":4,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["p","abs","abs","abs"]}] */ //The code to achieve that: function aggregateData(data){ const output = []; for (let obj of data){ let temp_arr = []; //incase we have multiple objects in our data array for (let key in obj){ if (Array.isArray(obj[key])){ //console.log('array', obj[key]) if (key == "StudentID"){ let temp_index = 0; for (let item of obj[key]){ if (item != temp_index){ temp_arr.push({"studentID": item}) temp_index = parseInt(item); } } } else{ //not studentID let temp_index = 0; for (let i = 0; i < obj[key].length; i++){ temp_index = parseInt(obj["StudentID"][i]); if (temp_arr[temp_index - 1].hasOwnProperty(key)){ temp_arr[temp_index - 1][key].push(obj[key][i]); } else { temp_arr[temp_index - 1][key] = [obj[key][i]]; } } } } else { //console.log('string', obj[key])+ for (let i = 0; i < temp_arr.length; i++){ if (temp_arr[i].hasOwnProperty(key)){ temp_arr[i][key].push(obj[key]); } else { temp_arr[i][key] = obj[key]; } } } } output.push(temp_arr); } return output; } console.log(aggregateData(data));

Output is:

[
  [
    {"StudentID":1,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["p","p","pdg","p"]},
    {"StudentID":2,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["abs","cc","p","abs"]},
    {"StudentID":3,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["p","p","abs","p"]},
    {"StudentID":4,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["p","abs","abs","abs"]}
  ]
]

Note it is wrapped in one more array than you wanted in your question because it is not clear if your data array will have more than one element or not (ie maybe for another module code or something), so I made it as general as possible.

For example if we have this as the input:

const data = [
    {
    "StudentID":["1","1","1","1","2","2","2","2","3","3","3","3","4","4","4","4"],
    "ModuleCode": "DES3095-N",
    "WeekNum":["1","2","3","4","1","2","3","4","1","2","3","4","1","2","3","4"],
    "Status":["p","p","pdg","p","abs","cc","p","abs","p","p","abs","p","p","abs","abs","abs"]
    },
    {
    "StudentID":["1","1","1","1","2","2","2","2","3","3","3","3","4","4","4","4"],
    "ModuleCode": "DES4095-P",
    "WeekNum":["1","2","3","4","1","2","3","4","1","2","3","4","1","2","3","4"],
    "Status":["p","p","pdg","p","abs","cc","p","abs","p","p","abs","p","p","abs","abs","abs"]
    }
  ];

Then we get this as the output (ie an array for each moduleCode):

[
  [
    {"StudentID":1,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["p","p","pdg","p"]},
    {"StudentID":2,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["abs","cc","p","abs"]},
    {"StudentID":3,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["p","p","abs","p"]},
    {"StudentID":4,"ModuleCode:"DES3095-N","WeekNum":["1","2","3","4"],"Status":["p","abs","abs","abs"]}
  ],
  [
    {"StudentID":1,"ModuleCode:"DES4095-P","WeekNum":["1","2","3","4"],"Status":["p","p","pdg","p"]},
    {"StudentID":2,"ModuleCode:"DES4095-P","WeekNum":["1","2","3","4"],"Status":["abs","cc","p","abs"]},
    {"StudentID":3,"ModuleCode:"DES4095-P","WeekNum":["1","2","3","4"],"Status":["p","p","abs","p"]},
    {"StudentID":4,"ModuleCode:"DES4095-P","WeekNum":["1","2","3","4"],"Status":["p","abs","abs","abs"]}
  ]
]

We can possibly do this cleaner by converting to a Map first and then using some map filter reduce functions but this does the job too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM