Reputation: 3
I came across this topic: Merge multiple array of objects and sum duplicate values javascript, and it was so close to something I was trying to do.
I essentially need the same thing, but I need the average of the values instead of the sum. What I thought would do the trick is:
var array1 = [{
price: "2",
ref: "A"
},
{
price: "20",
ref: "B"
},
{
price: "23",
ref: "C"
},
{
price: "23",
ref: "D"
}
];
var array2 = [{
price: "12",
ref: "A"
},
{
price: "5",
ref: "B"
},
{
price: "23",
ref: "E"
},
{
price: "23",
ref: "F"
}
];
var array3 = [{
name: "Blah",
fcp: "erol"
},
{
name: "Blah2",
fcp: "tpep"
}
];
var averagedArr = 2
var result = array1.concat(array2, array3).reduce(function(acc, curr) {
if (curr.ref) {
var fromMap = acc.map[curr.ref];
if (!fromMap) {
acc.map[curr.ref] = fromMap = {
price: 0,
ref: curr.ref
}
acc.result.push(fromMap);
}
fromMap.price += parseFloat(curr.price);
fromMap.price = parseFloat(fromMap.price/averagedArr);
} else {
acc.result.push(curr);
}
return acc;
}, {
map: {},
result: []
}).result;
console.log(result);
It isn't working because it seems to be averaging each price as it is added and not after they have been added all together. For example instead of for ref:B
the result being 12.5
(20+5 divided by 2) the result is 7.5
(20/2=10; 10+5=15; 15/2 = 7.5). If anyone could help me figure this out I would be most appreciative.
I would have just commented on the original topic to @Grundy who provided the response I was using, but this is my first question and I can't comment.
Here is the fiddle. https://jsfiddle.net/5xqbk9Lg/
Thanks in advance!
Upvotes: 0
Views: 431
Reputation: 386654
You could collect all values in a hash table and create a data set for the result if a new hash entry is created. Later collect price and count and build the average of the actual ref
.
var array1 = [{ price: "2", ref: "A" }, { price: "20", ref: "B" }, { price: "23", ref: "C" }, { price: "23", ref: "D" }],
array2 = [{ price: "12", ref: "A" }, { price: "5", ref: "B" }, { price: "23", ref: "E" }, { price: "23", ref: "F" }],
array3 = [{ name: "Blah", fcp: "erol" }, { name: "Blah2", fcp: "tpep" }],
hash = Object.create(null),
result = [];
[array1, array2, array3].forEach(function (a) {
a.forEach(function (b) {
if ('ref' in b) {
if (!hash[b.ref]) {
hash[b.ref] = { result: { ref: b.ref, avg: 0 }, sum: 0, count: 0 };
result.push(hash[b.ref].result);
}
hash[b.ref].sum += +b.price,
hash[b.ref].count++;
hash[b.ref].result.avg = hash[b.ref].sum / hash[b.ref].count;
}
});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2
Reputation: 778
Just change
fromMap.price = parseFloat(fromMap.price/averagedArr);
to
fromMap.finalPrice = parseFloat(fromMap.price/averagedArr);
and use the finalPrice variable as your result. The problem is that you are dividing by averagedArr for every item you add to the price, not just at the end-exactly what you are describing is the error. By using a separate variable to store your final result you aren't diving the sum each time.
Upvotes: 0