Reputation: 65600
I've got some CSV data that looks like this, showing pass rates by organisation by year:
org,org_cat,2004_passed,2004_total,2005_passed,2005_total,2006_passed,2006_total
GSK,industry,35,100,45,100,55,100
I'm working in D3, and I'd like to end up with a dictionary of organisations like this:
data = {
'GSK': {
'org_cat': 'industry',
'data': [
{ 'year': 2004, 'passed': 35, 'total': 100 },
{ 'year': 2005, 'passed': 45, 'total': 100 },
{ 'year': 2006, 'passed': 55, 'total': 100 }
]
]
}
Most of this is straightforward, but I've got very messy code for the year columns:
var data = {};
allData.forEach(function(d) {
data[d.org] = {
'category': d.org_cat,
'data': []
};
for (var k in d) {
var temp = {};
for (var k in d) {
if (patt.test(k)) {
var res = k.split("_");
if (res[0] in temp) {
temp[res[0]][res[1]] = +d[k];
} else {
temp[res[0]] = {};
temp[res[0]][res[1]] = +d[k];
}
}
}
var tempArr = [];
for (var y in temp) {
var tempDict = {};
tempDict.year = y;
tempDict.passed = temp[y].passed;
tempDict.total = temp[y].total;
tempArr.push(tempDict);
}
// TODO: sort by year in case the keys got shuffled
data[d.org].data = tempArr;
}
});
Is there a way to simplify this horrid code?
It's safe to assume that each row is a unique organisation.
Upvotes: 0
Views: 55
Reputation: 10642
I don't see why you need D3 to do this. You're code doesn't use it either. Here's how I would do it, I'm sure there's another simpler way but it may help you either way :
Jsfiddle : https://jsfiddle.net/thatOneGuy/dnvheznk/1/
I converted the data to JSON to use with JSFiddle, but you already know how to loop through CSV so just overwrite line 14 :
for (var i = 0; i < data.length; i++) { //loop through data array (this is so you can use this on a bigger sized array)
To your loop :
allData.forEach(function(d, i) { //but add the 'i' to index
Here is full commented code with converted JSON data :
var data = [{ //data set converted to JSON for easier use
"org": "GSK",
"org_cat": "industry",
"2004_passed": 35,
"2004_total": 100,
"2005_passed": 45,
"2005_total": 100,
"2006_passed": 55,
"2006_total": 100
}];
var newData = {}; //new data container
for (var i = 0; i < data.length; i++) { //loop through data array (this is so you can use this on a bigger sized array)
var thisObj = {}; //create empty object
thisObj.org_cat = data[i].org_cat; //set org_cat
thisObj.data = []; //set data to empty array to populate later
for (var key in data[i]) { //loop through data[i]
if (key != 'org' && key != 'org_cat') { //check this key is not org or org_cat
var thisData = {}; //create empty data object
var thisYear = key.toString().substring(0, 4); //get year by using substring
thisData.year = thisYear; //set year
thisData.passed = data[i][thisYear + '_passed']; //set passed at this year
thisData.total = data[i][thisYear + '_total']; //set total at this year
thisObj.data.push(thisData); //push this data to data array
}
}
var uniqueDates = []; //set empty array to use to remove duplicate items in data array
for (var j = 0; j < thisObj.data.length; j++) { //loop through data array created earlier
if (uniqueDates.indexOf(thisObj.data[j].year) < 0) { //if this year doesn't exist in unique array above, push it in
uniqueDates.push(thisObj.data[j].year); //push it in
} else {
thisObj.data.splice(j--, 1); //remove duplicate data
}
}
newData[data[i].org] = thisObj; //set data @ current org to be object created above
}
console.log('newData', newData) //log new data
Upvotes: 2