alexandremoraes alexandremoraes - 1 year ago 64
Javascript Question

Calculate new average from old average

I am building a rating system where the maximum value is

5
and the minimum is
1
.

I have the following rating information:

{
timesRated: 2,
worstRateSent: 1,
bestRateSent: 5,
overall: 3
}


Based on that, I know 2 persons rated this item. One of them rated
1
, the other one rated
5
, resulting an overall of
3
.

How can I keep calculating the overall when new ratings are input?

E.g. If a user rates this item as
3
. How to calculate the new overall?

{
timesRated: 3, // Since a new rate was added
worstRateSent: 1, // Keeps 1 since the rate sent was `3`
bestRateSent: 5, // Keeps 5 since the rate sent was `3`
overall: ?
}


Any help is appreciated :D

Answer Source

Basically, the way to do this would be to recalculate the total ratings by multiplying overall * timesRated then you would add the new rating to that number, increment timesRated by 1, and then divide the new total by the new number of times rated as your new overall.

As @Brian pointed out, you would have to deal with rounding errors, which can largely be accomplished with the use of Math.ceil() I can't guarantee this will be perfect, but it should definitely get you on the right track.

Let me know if you have any questions!

var ratings = {
  timesRated: 0,
  worstRating: 0,
  bestRating: 0,
  overall: 0,
  addRating: function (newRating) {
    newRating = Number(newRating);
    if (!this.worstRating || newRating < this.worstRating) {
      this.worstRating = newRating;
    }
    if (!this.bestRating || newRating > this.bestRating) {
      this.bestRating = newRating;
    }
    var totalRatings = Math.ceil(this.overall*this.timesRated);
    totalRatings += newRating;
    this.timesRated++;
    this.overall = totalRatings / this.timesRated;
  }
};
$("button").on("click", function(){
  var newRating = $(this).attr("value");
  ratings.addRating(newRating);
  $("#timesRated").text(ratings.timesRated);
  $("#worstRating").text(ratings.worstRating);
  $("#bestRating").text(ratings.bestRating);
  $("#avgRating").text(ratings.overall.toFixed(2));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  Times Rated: <span id="timesRated"></span><br/>
  Worst Rating: <span id="worstRating"></span><br/>
  Best Rating: <span id="bestRating"></span><br/>
  Average Rating: <span id="avgRating"></span><br/>
</div>
<br/>
Add Rating: <button value="1">1</button> <button value="2">2</button> <button value="3">3</button> <button value="4">4</button> <button value="5">5</button>

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download