Reputation: 5000
I have an API that returns indicator data in this format:
[
{
"concept": "population",
"year": 2012,
"value": 9.5,
"country-name": "Sweden",
},
{
"concept": "education",
"year": 2012,
"value": 12,
"country-name": "Sweden",
},
{
"concept": "population",
"year": 2012,
"value": 5,
"country-name": "Norway",
},
{
"concept": "eduction",
"year": 2012,
"value": 12,
"country-name": "Norway",
}
]
Based on this, I typically need to group this by country and year to get something like:
var data = [
{id : Sweden, population : 9.5, education: 12},
{id : Norway, population : 5, education: 12},
]
Or just by country and year-values as an array:
var data = [
{id : Sweden, values : [ { year : 2012, population : 9.5, education: 12 }, {...} ]},
{id : Norway, values : [ { year : 2012, population : 5, education: 12 }, {...} ]},
]
Upvotes: 0
Views: 66
Reputation: 5963
You might find an object easier to work with than an array:
var data = {};
indicatordata.forEach(function(item){
var country = item['country-name'];
var year = item.year;
data[country] = data[country] || {id: item['country-name'], values: {}};
var values = data[country].values;
values[year] = values[year] || {};
values[year][item.concept] = item.value;
});
Upvotes: 0
Reputation: 25273
You can do it with D3. d3.nest
and Array.prototype.reduce
specifically. The code is declarative and easy to maintain.
var rawData = [
{
"concept": "population",
"year": 2012,
"value": 9.5,
"country-name": "Sweden",
},
{
"concept": "education",
"year": 2012,
"value": 12,
"country-name": "Sweden",
},
{
"concept": "population",
"year": 2012,
"value": 5,
"country-name": "Norway",
},
{
"concept": "eduction",
"year": 2012,
"value": 12,
"country-name": "Norway",
}
];
var data = d3.nest()
.key(function(d)
{
return d['year'];
})
.key(function(d)
{
return d['country-name'];
})
.rollup(function(group)
{
return group.reduce(function(result, d)
{
result[d['concept']] = d['value'];
return result;
}, {});
})
.entries(rawData);
console.log(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Upvotes: -1
Reputation: 318322
You can do it yourself, just iterate and create whatever you need, something like
var data = [];
json.forEach(function(item) {
var country = item['country-name'],
match = false,
obj = {}
data.forEach(function(dataItem, i) {
if (dataItem.id === country) {
match = true;
obj = data[i];
}
});
obj.id = country;
obj[item.concept] = item.value;
if (!match) data.push(obj)
});
Upvotes: 2