Finding the mode (most often) of a set of numbers

Hello, everyone!

I am currently in the process of creating and perfecting a statistics calculator. Everything has been going great, except for one particular function, and that is the mode, or most often, of the number set. I currently have this function for finding repeated numbers:

  mode = [];
  for (i = 0; i < list.length; i++) {
    for (j = i + 1; j < list.length; j++) {
      if (list[i] === list[j] && mode.includes(list[i]) === false) {
        mode.push(list[i]); //creates an array for the mode(s) (WIP)
  console.log("The mode(s) are " + mode + " ~ WIP ~"); //displays the mode(s) (WIP)

The problem with this function is that it works well for finding duplicates, but it will display all duplicates, and not the most repeated number. For example, the number set [10, 17, 16, 14, 18, 3, 13, 16, 4, 2, 6, 20, 16, 5, 11, 7, 19, 11] returns both 11 and 16 as modes, but 16 is the only mode because it is repeated twice, while 11 is only repeated once. Does anyone have a simple way of making this work, like putting the possible modes into an array, and checking for the most repeated in the array? Any help would be greatly appreciated. Thanks!

~ TBNRmyth


The problem with your current code is this line:

if (list[i] === list[j] && mode.includes(list[i]) === false) {

With reference to the sample array you provided, you are currently only checking if a number occurs more than once (it and it can be any number of times more than once—both 11 and 16 meet this criterion); and if it’s not in the array mode then it gets pushed in—so both 11 and 16 get pushed in once and you get [11, 16].

I would personally approach this differently, here are some suggestions:

  • Sort the array first and process it knowing that numbers that are the same will always be next to each other
  • Use a dictionary-like object (for example, {16: 3, 11: 2}) to tally every number first, then return the key that has the highest count

There are probably even simpler ways but don’t know enough, I can’t think of any at the moment. I hope that helps. :slight_smile:

There are a few ways to do this. I would do something like this:

var mode;
list.reduce ((t,n)=>{  
   let cur=list.reduce((nt,nn)=>{  if(nn===n){ return nt+1; } return nt; },0);
  if (cur>t){ mode=n;  return cur; .}
  return t;

But Im sure there are better ways to do it.

Your solution returns 3 instead of 16.

I guess I should’ve mentioned earlier, I do have list.sort(function(a,b){return a-b}); at the beginning of the function, which sorts it flawlessly. Second, how would I go about making an object like you suggested? I’m not super great at JavaScript right now, so I’m a bit lost on how to go about doing that. Thank you for your response though!

Thank you for your response. I tried your suggestion out, and it works in the sense that it uses the number that is repeated the most, however, it only allows for one mode. For example, if I put in a number set that has 3 11’s and 3 16’s, it results with “The mode(s) are 11”. I’m not too sure how to fix that. Any suggestions?

Sorry I’m at work right now and typing code on my phone is a pain. But basically I would do it the way @honmanyau suggested. Loop through the array and build an object with the keys == the value from the array and the value == to the count. Then just output the one/s with highest number. If you need it, when I get off work tonight I can show you some code.