I am trying to calculate the average of values with the same key in a array of objects. Not all the Objects consist of the same values as the other but I still want the average returned depending on how many times it appears in the array. For example I want
const Object1 = [{
2005: 5.6,
2006: 5.2
}, {
2005: 5.6,
2006: 5.7,
2007: 5.4
}, {
2005: 5.6,
2006: 5.9,
2007: 5.8
}]
To return
{
2005: 5.599999999999999,
2006: 5.6000000000000005,
2007: 5.6
}
This is what I have tried so far. Right now the problem is that I have no way to / it by the amount of times it appears. And if it is missing the year the value becomes undefined and this causes the result to be NaN.
const Object1 = [{
2005: 5.6,
2006: 5.2
}, {
2005: 5.6,
2006: 5.7,
2007: 5.4
}, {
2005: 5.6,
2006: 5.9,
2007: 5.8
}]
const years = Object.keys(Object.assign({}, ...Object1));
const Result = years.reduce((a, v) => ({
...a,
[v]: v
}), {})
console.log(Result)
years.map((year) => {
const value =
Object1.map(function(obj) {
return obj[year]
}).reduce(function(a, b) {
return (a b)
}) / years.length
Result[year] = value
})
console.log(Result)
CodePudding user response:
You could group points by year and calculate points solely based on each group
const object1 = [
{
2005: 5.6,
2006: 5.2,
},
{
2005: 5.6,
2006: 5.7,
2007: 5.4,
},
{
2005: 5.6,
2006: 5.9,
2007: 5.8,
},
];
const groupPointByYears = object1.reduce((map, obj) => {
for (const [year, point] of Object.entries(obj)) {
if (!map.has(year)) {
map.set(year, []);
}
map.get(year).push(point);
}
return map;
}, new Map());
console.log(Array.from(groupPointByYears));
const res = Object.fromEntries(
Array.from(groupPointByYears).map(([year, points]) => [
year,
points.reduce((sum, point) => sum point, 0) / points.length,
])
);
console.log(res);
CodePudding user response:
const years = Object1.reduce(( prev, curr ) => {
for (const key in curr) prev[key] = (prev[key] || []).concat(curr[key])
return prev
}, {})
const Result = {}
for (const year in years) {
Result[year] = years[year].reduce(( prev, val ) => prev val, 0) / years[year].length
}
console.log(Result)
this code first puts all values of every year in an array in an object (that's what the first reduce does) then it loops over every year and adds the average (sum of all values divided by the amount of values) to the Result object
CodePudding user response:
I made some changes based on your code
const Object1 = [{
2005: 5.6,
2006: 5.2
}, {
2005: 5.6,
2006: 5.7,
2007: 5.4
}, {
2005: 5.6,
2006: 5.9,
2007: 5.8
}]
const years = Object.keys(Object.assign({}, ...Object1));
const Result = years.reduce((a, v) => ({
...a,
[v]: v
}), {})
console.log(Result)
years.map((year) => {
// Filter out keywords while removing undefined ones
var filteredYear = Object1.map(function(obj) {
return obj[year]
}).filter(e=>e!=undefined)
// Perform a reduce calculation with the filtered results
const value =
filteredYear.reduce(function(a, b) {
return (a b)
}) / filteredYear.length
Result[year] = value
})
console.log(Result)