4

I have several array to deal with. I need to extract the most duplicate value from each array.

From [3, 7, 7, 7], I need to find the value 7. Each array size is 4. For now, I don't have to think about when the most duplicate values are more than one such as [3, 7, 7, 7]. All the values are a number.

I looked around the web. I found several ways to make an array to become uniq(). But I haven't found a way to get the duplicate value. I am using jQuery, but raw JavaScript is fine for this task.

TK.
  • 27,073
  • 20
  • 64
  • 72
  • 1
    Algorithmically, I'm curious to know the most efficient way to do this (besides iterating the array and counting refs). – Plynx Mar 13 '10 at 22:53

5 Answers5

8

Not perfect in terms of efficiency, but does the job:

var nums = [3, 7, 7, 7];
var freqs = {};
var max_index;
var max_value = -1/0; // Negative infinity.

$.each(nums, function(i, v) {
  if (freqs[v] != undefined) {
    freqs[v]++;
  } else {
    freqs[v] = 1;
  }
});
$.each(freqs, function(num, freq) {
  if (freq > max_value) {
    max_value = freq;
    max_index = num;
  }
});

if (max_index != undefined) {
  alert("Most common element is " + max_index + " with " + max_value + " repetition(s).");
}
​
Max Shawabkeh
  • 37,799
  • 10
  • 82
  • 91
6

Here's a simpler and faster version using only JavaScript:

var arr = [3, 7, 7, 7, 10, 10, 8, 5, 5, 5, 5, 20, 20, 1];
var counts = {}, max = 0, res;
for (var v in arr) {
  counts[arr[v]] = (counts[arr[v]] || 0) + 1;
  if (counts[arr[v]] > max) { 
    max = counts[arr[v]];
    res = arr[v];
  }
}
alert(res + " occurs " + counts[res] + " times");

Note that this is a much more efficient since you're looping over the data once, if you're sorting very large arrays this will start to matter.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • This solution doesn't work. It always returns the last value in the array regardless of its frequency. – Xavi Mar 17 '10 at 13:46
  • @Xavi - Good point, I was accessing the object array incorrectly, fixed and a bit more compact/efficient now...though less readable. – Nick Craver Mar 17 '10 at 14:56
  • Worked extremely well in a case where looping through the data only once was very important. Thank you. It might be helpful for less experienced users if you added a few lines on the logic involved here, it always helps as cases are modified to personal use. – Thomas Oct 11 '17 at 23:41
3

Here's a quick example using javascript:

function mostFrequent(arr) {
    var uniqs = {};

    for(var i = 0; i < arr.length; i++) {
        uniqs[arr[i]] = (uniqs[arr[i]] || 0) + 1;
    }

    var max = { val: arr[0], count: 1 };
    for(var u in uniqs) {
        if(max.count < uniqs[u]) { max = { val: u, count: uniqs[u] }; }
    }

    return max.val;
}

A quick note on algorithmic complexity -- because you have to look at each value in the array at least once, you cannot do better than O(n). This is assuming that you have no knowledge of the contents of the array. If you do have prior knowledge (e.g. the array is sorted and only contains 1s and 0s), then you can devise an algorithm with a run time that is some fraction of n; though technically speaking, it's complexity is still O(n).

Xavi
  • 20,111
  • 14
  • 72
  • 63
1
Array.prototype.mostFreq=function(){
 var what, a= this.concat(), ax, freq,
 count, max=0, limit= a.length/2;
 while(a.length){
  what= a.shift();
  count=1; 
  while((ax= a.indexOf(what))!= -1){
   a.splice(ax,1); // remove counted items  
   ++count;
  }
  // if any item has more than half the array, quit counting
  if(count> limit) return what; 
  if(count> max){
   freq= what;
   max= count;
  }
 }
 return freq;
}
var a=[1,1,2,5,4,2,7,7,1,1,1,3,7,7,3,4,3,7,3,5,6,2,3,1,1,7,7,2,4,3,6,7,6,6]
alert(a.mostFreq())
kennebec
  • 102,654
  • 32
  • 106
  • 127
0

Another solution can be based on Array.reduce():

var arr = [1,1,2,5,4,2,10,10,1,1,1,3,10,10,3,4,3,10,3,5,6,2,3,1,1,10,10,2,4,3,6,10,6,6];

var result = arr.reduce(function(acc, e) {
    acc[e] = (acc[e] || 0) + 1;
    if (acc[e] > acc.mostFreq.freq) {
        acc.mostFreq.value = e;
        acc.mostFreq.freq = acc[e];
    }
    return acc;
}, {"mostFreq": {"value": 0, "freq": 0}}).mostFreq;

console.log('The most duplicated elements is: ' + JSON.stringify(result));
gaetanoM
  • 41,594
  • 6
  • 42
  • 61