Calculate average from data in array of object and store in specific key from object

Viewed 63

Suppose I have an array of object,

const book = [{'name':'alpha','readingTime':1231},{'name':'alpha','readingTime':1254}, 
              {'name':'beta','readingTime':190},
              {'name':'theta','readingTime':909},{'name':'theta','readingTime':10}]

I want to calculate average for each name, such that expected O/P is

**{alpha:1242.5, beta:190, theta:459.5}**

For this I tried as ,

let calculatedValue = book.reduce((acc,curr) => acc+curr.readingTime,0)/book.length

This gives me average for all the object.

I'm unable to form logic corresponding to it.

Any guidance would really be helpful. If anyone needs any further information please let me know.

4 Answers

You could group by name and get the count and total of readingTime and build a new object with the averages.

const
    books = [{ name: 'alpha', readingTime: 1231 }, {  name: 'alpha', readingTime: 1254 }, { name: 'beta', readingTime: 190 }, { name: 'theta', readingTime: 909 }, { name: 'theta', readingTime: 10 }],
    averages = Object.fromEntries(
        Object.entries(books.reduce((r, { name, readingTime }) => {
            r[name] = r[name] || { count: 0, total: 0 };
            r[name].count++;
            r[name].total += readingTime;
            return r;
        }, {}))
        .map(([k, { count, total }]) => [k, total / count])
    );

console.log(averages);

Here is another simple solution for you.

const book = [{'name':'alpha','readingTime':1231},{'name':'alpha','readingTime':1254}, 
{'name':'beta','readingTime':190},
{'name':'theta','readingTime':909},
{'name':'theta','readingTime':10}]

const result = {};

Object.values(book.reduce((acc, current) => {
    acc[current.name] = acc[current.name] || { count: 0, total: 0 };
    acc[current.name].total += current.readingTime;
    acc[current.name].count += 1;
    acc[current.name].name = current.name;

    return acc;
}, {})).forEach(({ name, count, total }) => { result[name] = total / count; });

console.log(result)

Need more optimization (Fell free to edit ) but it works

const book = [{'name':'alpha','readingTime':1231},{'name':'alpha','readingTime':1254}, 
              {'name':'beta','readingTime':190},
              {'name':'theta','readingTime':909},{'name':'theta','readingTime':10}]


function avgReading(arr){
let alpha = { lengtharr : 0 ,readingAll : 0 };
let beta = {...alpha};
let theta = {...alpha};
arr.forEach((item) => {
  if(item.name === 'alpha') 
    alpha.lengtharr++;
    alpha.readingAll = alpha.readingAll + item.readingTime;
  if(item.name === 'beta') 
    beta.lengtharr++;
    beta.readingAll = beta.readingAll + item.readingTime;
 if(item.name === 'theta')
    theta.lengtharr++;
    theta.readingAll = theta.readingAll + item.readingTime;
});
const obj = {
'alpha' : alpha.readingAll /alpha.lengtharr,
'beta' : beta.readingAll /beta.lengtharr,
'theta' : theta.readingAll /theta.lengtharr
}
return obj;
}
console.log(avgReading(book))

Tyy this

let obj = book.reduce((acc,curr) => {
    acc[curr['name']] = acc[curr['name']]?acc[curr['name']]:[0,0]
    acc[curr['name']][0]+=curr['readingTime'];
    acc[curr['name']][1]+=1;
    return acc;
}, {})

let calculatedValue ={};
Object.keys(obj).forEach(key=>calculatedValue[key]=obj[key][0]/obj[key][1])
Related