I have an array like this:
var data =
[
{label:1, quater :'Q1', y:34},
{label:2, quater:'Q1', y:20},
{label:3, quater:'Q1', y:30},
{label:1, quater:'Q2', y:77},
{label:2, quater:'Q2', y:52},
{label:3, quater:'Q2', y:3},
{label:1, quater:'Q3', y:65},
{label:2, quater:'Q3', y:12},
{label:3, quater:'Q3', y:9},
{label:1, quater:'Q4', y:77},
{label:2, quater:'Q4', y:34},
{label:3, quater:'Q4', y:5}
];
My goal is to add "percent" into each object. Each "percent" is the percentage of the value of y in current object devided by the sum of values of y in quater from Q1 to Q4. For example, the percent in first boject should be 34/(34+77+65+77) The code below is what I tried. It works and calculats the data correctly. I am new to javascript, so I calculate the data step by step which makes the code look long.
I am wondering what is the smarter way to calculate the data to make the code shorter? Thanks!
var quater = ["Q1","Q2","Q3","Q4"];
var sum = 0;
var arr = [];
for(var i = 0; i<quater.length; i++){
for(var j = 0; j<data.length; j++){
if (data[j]['quater'] == quater[i])
sum = sum + data[j]['y'];
}
//console.log(sum)
arr.push({
'quater': quater[i],
'sum': sum
})
sum = 0;
}
var arr1 = [];
var percent;
for(var i = 0; i<data.length;i++){
for(var j = 0; j<arr.length; j++){
if(data[i]['quater'] == arr[j]['quater']){
percent = data[i]['y']/arr[j]['sum'];
}
}
//console.log(percent)
arr1.push({
'label': data[i]['label'],
'y': data[i]['y'],
'quater': data[i]['quater'],
'percent': percent
});
}
console.log(arr1)
I have an array like this:
var data =
[
{label:1, quater :'Q1', y:34},
{label:2, quater:'Q1', y:20},
{label:3, quater:'Q1', y:30},
{label:1, quater:'Q2', y:77},
{label:2, quater:'Q2', y:52},
{label:3, quater:'Q2', y:3},
{label:1, quater:'Q3', y:65},
{label:2, quater:'Q3', y:12},
{label:3, quater:'Q3', y:9},
{label:1, quater:'Q4', y:77},
{label:2, quater:'Q4', y:34},
{label:3, quater:'Q4', y:5}
];
My goal is to add "percent" into each object. Each "percent" is the percentage of the value of y in current object devided by the sum of values of y in quater from Q1 to Q4. For example, the percent in first boject should be 34/(34+77+65+77) The code below is what I tried. It works and calculats the data correctly. I am new to javascript, so I calculate the data step by step which makes the code look long.
I am wondering what is the smarter way to calculate the data to make the code shorter? Thanks!
var quater = ["Q1","Q2","Q3","Q4"];
var sum = 0;
var arr = [];
for(var i = 0; i<quater.length; i++){
for(var j = 0; j<data.length; j++){
if (data[j]['quater'] == quater[i])
sum = sum + data[j]['y'];
}
//console.log(sum)
arr.push({
'quater': quater[i],
'sum': sum
})
sum = 0;
}
var arr1 = [];
var percent;
for(var i = 0; i<data.length;i++){
for(var j = 0; j<arr.length; j++){
if(data[i]['quater'] == arr[j]['quater']){
percent = data[i]['y']/arr[j]['sum'];
}
}
//console.log(percent)
arr1.push({
'label': data[i]['label'],
'y': data[i]['y'],
'quater': data[i]['quater'],
'percent': percent
});
}
console.log(arr1)
Share
Improve this question
asked Feb 24, 2016 at 19:40
User2403User2403
1351 gold badge2 silver badges8 bronze badges
3 Answers
Reset to default 5Can make a simple object that has quater
's as keys and has the sums as values.
Then iterate array again and calculate percentage
var totals={};
data.forEach(function(item){
totals[item.quater] = (totals[item.quater] || 0 ) + item.y;
});
// totals now looks something like {Q3:18, Q1:16, Q4:66, Q1:12}
data.forEach(function(item){
item.percent = 100 * item.y / totals[item.quater];
});
Assumes label
is unimportant such as representing year. If not concatenate label , delimiter and quater
into object keys
EDIT: i may have this backwards and need label
's as keys. Approaach is same
You can use forEach
or map
to this more efficiently. The first map
is used to calculate the totals, the second map
is used to calculate the percentages. See charlietfl answer, who beat me to the answer, for the forEach
method which is pretty much identical.
var data =
[
{label:1, quater :'Q1', y:34},
{label:2, quater:'Q1', y:20},
{label:3, quater:'Q1', y:30},
{label:1, quater:'Q2', y:77},
{label:2, quater:'Q2', y:52},
{label:3, quater:'Q2', y:3},
{label:1, quater:'Q3', y:65},
{label:2, quater:'Q3', y:12},
{label:3, quater:'Q3', y:9},
{label:1, quater:'Q4', y:77},
{label:2, quater:'Q4', y:34},
{label:3, quater:'Q4', y:5}
];
quartersum = {}
data.map(function(entry) {
quartersum[entry.label] = (quartersum[entry.label]||0) + entry.y
})
data.map(function(entry) {
entry.percent = entry.y / quartersum[entry.label] * 100;
document.write(JSON.stringify(entry) + '<br>')
})
Try this.
I just followed the procedure of pushing the objects simultaneoulsy as I was calculating the percent values.
<script>
var data =
[
{label:1, quarter :'Q1', y:34},
{label:2, quarter:'Q1', y:20},
{label:3, quarter:'Q1', y:30},
{label:1, quarter:'Q2', y:77},
{label:2, quarter:'Q2', y:52},
{label:3, quarter:'Q2', y:3},
{label:1, quarter:'Q3', y:65},
{label:2, quarter:'Q3', y:12},
{label:3, quarter:'Q3', y:9},
{label:1, quarter:'Q4', y:77},
{label:2, quarter:'Q4', y:34},
{label:3, quarter:'Q4', y:5}
];
var quater = ["Q1","Q2","Q3","Q4"];
var sum = 0;
var arr = [];
for(var i = 0; i<data.length; i++){
for(var j = 0; j<data.length; j++){
if (data[j]['quarter'] == quater[i])
sum = sum + data[j]['y'];
}
percent = data[i]['y']/sum;
//console.log(percent)
arr.push({
'label': data[i]['label'],
'y': data[i]['y'],
'quater': data[i]['quarter'],
'percent': percent
});
sum = 0;
}
console.log(arr);
</script>