I have data with value like so:
let data = [
{
"id": "A",
"year": "2019",
"score": 105.38
},
{
"id": "A",
"year": "2020",
"score": 91.8
},
{
"id": "B",
"year": "2020",
"score": 104.18
},
{
"nip": "B",
"year": "2019",
"score": 101.31
},
{
"id": "C",
"year": "2020",
"score": 91.8
},
{
"id": "C",
"year": "2019",
"score": 106.6
}
]
I want to calculate the average score for each id so the result would be something like this:
let result = [{"id": A, "average":143.89}, {"id":B, "average":154.83}, {"id":C, "average":99.2}]
How do I do that?
You need to go through the array remembering the sum and count of entries you've seen per ID, then you can build your result array with the average (sum / count) for each ID, something like this:
const countsAndSums = new Map();
for (const {id, score} of data) {
const entry = countsAndSums.get(id);
if (!entry) {
// Haven't seen this ID before
countsAndSums.set(id, {id, count: 1, sum: score});
} else {
// Update the count and sum for this ID
++entry.count;
entry.sum += score;
}
}
// Now you can build the array
const result = [...countsAndSums.values()].map(({id, count, sum}) => ({id, average: sum / count}));
Live Example:
let data = [
{
"id": "A",
"year": "2019",
"score": 105.38
},
{
"id": "A",
"year": "2020",
"score": 91.8
},
{
"id": "B",
"year": "2020",
"score": 104.18
},
{
"nip": "B",
"year": "2019",
"score": 101.31
},
{
"id": "C",
"year": "2020",
"score": 91.8
},
{
"id": "C",
"year": "2019",
"score": 106.6
}
];
const countsAndSums = new Map();
for (const {id, score} of data) {
const entry = countsAndSums.get(id);
if (!entry) {
// Haven't seen this ID before
countsAndSums.set(id, {id, count: 1, sum: score});
} else {
// Update the count and sum for this ID
++entry.count;
entry.sum += score;
}
}
// Now you can build the array
const result = [...countsAndSums.values()].map(({id, count, sum}) => ({id, average: sum / count}));
console.log(result);
Here's a convoluted one-liner solution:
let data = [
{
"id": "A",
"year": "2019",
"score": 105.38
},
{
"id": "A",
"year": "2020",
"score": 91.8
},
{
"id": "B",
"year": "2020",
"score": 104.18
},
{
"id": "B",
"year": "2019",
"score": 101.31
},
{
"id": "C",
"year": "2020",
"score": 91.8
},
{
"id": "C",
"year": "2019",
"score": 106.6
}
];
const averages = Object.entries(data.reduce((acc, { id, score }) => ({ ...acc, [id]: [...(acc[id] || []), score] }), {}))
.map(([id, scores]) => ({ id, average: scores.reduce((acc, cur) => acc + cur, 0) / scores.length }));
console.log(averages);