Reputation: 8623
I have a data like this: (The real record has far more than this)
year type quantity
2011 A 1000
2012 B 1000
2012 C 1000
2012 A 1000
2015 A 1000
JSON:
[{year:2011, type:A, quantity:1000},...]
and i want to have the result like this: (I want every year and every type has a record there)
year type quantity
2011 A 1000
2011 B -
2011 C -
2012 A 1000
2012 B 1000
2012 C 1000
2015 A 1000
2015 B -
2015 C -
Is there any good way to do this? underscore solution is also welcomed!
Upvotes: 3
Views: 87
Reputation: 171679
Vanilla JS, includes final sort
var yrs = [], types = [], tmp={};
data.forEach(function(item){
// create arrays of years and types
if(yrs.indexOf(item.yr) === -1){
yrs.push(item.yr);
}
if(types.indexOf(item.type) === -1){
types.push(item.type);
}
// temp object used in next step to look for holes
tmp[item.yr + item.type] = true;
});
yrs.forEach(function(yr){
types.forEach(function(type){
// fill in holes
if(!tmp.hasOwnProperty(yr+type)){
data.push({yr: yr, type: type, qty: 0});
}
})
});
data.sort(function(a,b){
return b.yr === a.yr ? a.type > b.type : +a.yr - +b.yr
});
Upvotes: 1
Reputation: 3935
A bit optimized version with jquery
var source = [{year:2011, type: 'A', quantity:100},{year:2012, type: 'B', quantity:200}],
product = [],
types = {},
years = {},
quantities = {};
$.each(source, function(i){
var type = source[i].type,
year = source[i].year;
types[type]= true;
years[year]= true;
if (typeof quantities[type] == "undefined")
quantities[type] = {};
quantities[type][year] = source[i].quantity;
});
$.each(types, function(type){
var qts = quantities[type];
$.each(years, function(year){
var value = "-";
if (typeof qts[year] != "undefined")
value = qts[year];
product.push({year:year, type: type, quantity:value});
});
});
console.log(product);
Saves time by extracting the types and years in one loop, and doesn't store repeated values (so there's no need of .unique).
Upvotes: 1
Reputation: 456
Hope this will work with underscore:
var source = [{year: "2011", type: "A",...} ...];
var years = _.uniq(_.map(source , function(item){
return item.year;
}))
var types = _.uniq(_.map(source , function(item){
return item.type;
}))
var result = [];
_.each(years, function(yearItem){
_.each(types, function(typeItem){
var resultItem = _.find(source, function(item){
return item.year === yearItem && item.type === typeItem;
})
if(undefined === resultItem){
resultItem = {
year: yearItem,
type: typeItem,
quantity: "-"
};{}
}
result.push(resultItem);
})
})
Upvotes: 1