Reputation: 2354
My base data structure..
[{
month: 'Jan',day:1
cat: 'A',
type:'val', val: 20
},{
month: 'Jan',day:1
cat: 'B',
type:'val', val: 5
},{
month: 'Jan',day:2
cat: 'A',
type:'val', val: 10
},{
month: 'Jan',day:2
cat: 'B',
type:'val', val: 10
},{
month: 'Feb',day:1
cat: 'A',
type:'val', val: 30
},{
month: 'Feb',day:1
cat: 'B',
type:'val', val: 10
},{
month: 'Feb',day:2
cat: 'A',
type:'val', val: 20
},{
month: 'Feb',day:2
cat: 'B',
type:'val', val: 20
}];
The following is what I need to do:
a) get property 'val' for each unique property 'cat' and 'day' say cat:'A' and day:1
b) do an average of all values recd in above step, so for each unique property 'cat' and 'day' we get an avg. val
c)Find all objects in the array which has the above value for property 'cat' and 'day'
d) clone the objects such that the original object in array does not get changed
e) update the cloned objects type to'avg' and val to 'avg value recd in step (b)'
f) add the new objects to the base data array..
So, at the end the array will have double the values that it had earlier and the new objects to go in the array will be the following..
{
month: 'Jan',day:1
cat: 'A',
type:'avg', val: 25 //20+30/2
},{
month: 'Jan',day:1
cat: 'B','
type:'avg', val: 7.5 //5+10/2
},{
month: 'Jan',day:2
cat: 'A',
type:'avg', val: 15 //10+20/2
},{
month: 'Jan',day:2
cat: 'B',
type:'avg', val: 15 //10+20/2
},{
month: 'Feb',day:1
cat: 'A',
type:'avg', val: 25
},{
month: 'Feb',day:1
cat: 'B',
type:'avg', val: 7.5
},{
month: 'Feb',day:2
cat: 'A',
type:'avg', val: 15
},{
month: 'Feb',day:2
cat: 'B',
type:'avg', val: 15
}
ANSWER: Thanks to Nina, I was able to solve this, I was unable to explain my req correctly.. The following is what I was looking for ..
hash = Object.create(null),
result = data.map(function (a, i) {
var key = a.day + '|' + a.cat;
this[key] = this[key] || { indices: [], sum: 0 };
this[key].indices.push(i);
this[key].sum += a.val;
return { month: a.month, day: a.day, cat: a.cat, type: 'avg' };
}, hash);
Object.keys(hash).forEach(function (k) {
hash[k].indices.forEach(function (i) {
result[i].val = hash[k].sum / hash[k].indices.length;
});
});
final_result= $.merge( $.merge( [], data ), result );
Upvotes: 0
Views: 64
Reputation: 386736
This is a proposal in plain Javascript with an object as hash table for the wanted groups for the average calculation.
var data = [{ month: 'Jan', day: 1, cat: 'A', type: 'val', val: 20 }, { month: 'Jan', day: 1, cat: 'B', type: 'val', val: 5 }, { month: 'Jan', day: 2, cat: 'A', type: 'val', val: 10 }, { month: 'Jan', day: 2, cat: 'B', type: 'val', val: 10 }, { month: 'Feb', day: 1, cat: 'A', type: 'val', val: 30 }, { month: 'Feb', day: 1, cat: 'B', type: 'val', val: 10 }, { month: 'Feb', day: 2, cat: 'A', type: 'val', val: 20 }, { month: 'Feb', day: 2, cat: 'B', type: 'val', val: 20 }],
hash = Object.create(null),
result = data.map(function (a, i) {
var key = a.day + '|' + a.cat;
this[key] = this[key] || { indices: [], sum: 0 };
this[key].indices.push(i);
this[key].sum += a.val;
return { month: a.month, day: a.day, cat: a.cat, type: 'avg' };
}, hash);
Object.keys(hash).forEach(function (k) {
hash[k].indices.forEach(function (i) {
result[i].val = hash[k].sum / hash[k].indices.length;
});
});
console.log(result);
Upvotes: 2