3

Below I reproduce my code for calculate average ratings for foods.

3+4+5+2 / 4 should be equal to 3.5. But this not gives me the correct output. What's wrong with my code?

const ratings = [
  {food:3},
  {food:4},
  {food:5},
  {food:2}
];

let food = 0;

ratings.forEach((obj,index)=>{
  food = (food + obj.food)/++index
})

console.log("FOOD",food)

6 Answers 6

4

Despite of having several answers I would like to add mine focusing to improve the code quality:

  1. You can use destructuring in forEach() to just get the food property of the object as that is only the property you are interested with.
  2. Despite of dividing inside loop we can have only one division operation after the loop is completed. This saves a lot of computation when the array is huge(thousands of objects)
  3. You can use short hand like += in the loop for summing up the value.
  4. You can make a single line code in forEach()

const ratings = [
  {food:3},
  {food:4},
  {food:5},
  {food:2}
];

let foodTotal = 0;
let length = ratings.length;
ratings.forEach(({food})=> foodTotal += food);

console.log("FOOD",foodTotal/length);

Sign up to request clarification or add additional context in comments.

3 Comments

@PathumSamararathna I will suggest to use this answer. Not because this is mine but this will help you code optimally.
Sure!.even the first answer solved my problem. But this answer'll more help to the community.
In what sense does this answer improve code quality over simpler and more idiomatic answers like this one?
2

You'd use reduce to sum, then simply divide by rating's length

const ratings = [
  {food:3},
  {food:4},
  {food:5},
  {food:2}
];

const avg = ratings.reduce((a, {food}) => a + food, 0) / ratings.length;
console.log(avg);

2 Comments

You’re welcome. @PathumSamararathna You’ve accepted the wrong answer though. Even though it claims to be efficient and whatever, it isn’t. It introduces plenty of unneeded variables, uses forEach where reduce should be used, and so on.
This is indeed the most idiomatic JavaScript, and should be accepted in favor of any solution using forEach().
2

Here is another solution using .reduce()

const ratings = [
  {food: 3},
  {food: 4},
  {food: 5},
  {food: 2}
]
const average = ratings.reduce((a, b) => {
  return {food: a.food + b.food}
}).food / ratings.length

console.log('FOOD', average)

Comments

1

You need to divide by the number of elements after you have summed them together

const ratings = [
    {food:3},
    {food:4},
    {food:5},
    {food:2}
];

let food = 0;

ratings.forEach((obj,index)=>{
    food = (food + obj.food)
});

food = food / ratings.length;

console.log("FOOD",food)

Comments

1

You need to add the relative contribution to the average of each food.

Since average is - sum of items / number of items in your case it's

(3+4+5+2) / 4

Which we can split to

3/4 + 4/4 + 5/4 + 2/4

const ratings = [{"food":3},{"food":4},{"food":5},{"food":2}];

let food = 0;

ratings.forEach((obj) => {
  food = food + obj.food / ratings.length;
})

console.log("FOOD", food)

You can also use Array.reduce() to shorten the code a bit:

const ratings = [{"food":3},{"food":4},{"food":5},{"food":2}];

const food = ratings.reduce((r, { food }) => 
  r + food
, 0) / ratings.length;

console.log("FOOD", food)

Comments

0

What you are doing is 3/1 + 4/2 + 5/3 + 2/4 which is not equivalent to 3/4 + 4/4 + 5/4 + 2/4. What you can do is

ratings.forEach((obj,index)=>{
    food = (food + obj.food)
});

food = food / ratings.length;

console.log("FOOD",food)

If you are into functional way of doing things then I would use a reduce function to get the result.

const food = ratings.reduce((sum, { food }) => sum + food, 0) / ratings.length;

console.log("FOOD", food)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.