views:

222

answers:

6
var store = ['1','2','2','3','4'];

I want to find out that 2 appear the most in the array. How do I go about doing that?

+2  A: 

Make a histogram, find the key for the maximum number in the histogram.

var hist = [];
for (var i = 0; i < store.length; i++) {
  var n = store[i];
  if (hist[n] === undefined) hist[n] = 0;
  else hist[n]++;
}

var best_count = hist[store[0]];
var best = store[0];
for (var i = 0; i < store.length; i++) {
  if (hist[store[i]] > best_count) {
    best_count = hist[store[i]];
    best = store[i];
  }
}

alert(best + ' occurs the most at ' + best_count + ' occurrences');

This assumes either there are no ties, or you don't care which is selected.

Jamie Wong
Not necessary if the array is sorted, though. Then it can be a single-pass operation.
Thilo
As a side note, this is called the mode of the distribution.
André Caron
+10  A: 

I would do something like:

var store = ['1','2','2','3','4'];
var frequency = {};  // array of frequency.
var max = 0;  // holds the max frequency.
var result;   // holds the max frequency element.
for(var v in store) {
        frequency[store[v]]=(frequency[store[v]] || 0)+1; // increment frequency.
        if(frequency[store[v]] > max) { // is this frequency > max so far ?
                max = frequency[store[v]];  // update max.
                result = store[v];          // update result.
        }
}
codaddict
+1 For a better implementation of what I said :P
Jamie Wong
+1 - Very nice... But I would use a `for` loop to block corner cases where the array object has properties: http://jsfiddle.net/9eJd3/
Peter Ajtai
I'd suggest the addition of `if (store.hasOwnProperty(v))` in case someone has decided to modify Object or Array's prototype, as folks seem to be somewhat keen on that doing around here ;P
no
@no - That's not good enough, since `store` can have its own properties that **are not** values of the array. ( http://jsfiddle.net/vR5JK/ ). A `for` loop will do the trick though, since anything outside the values in the array are not included in `store[0]` to `store[store.length]`
Peter Ajtai
Ooops, by `for` loop I meant `for(var v=0; v < store.length; ++v){...}`.
Peter Ajtai
@Peter Ajtai - I saw your example, but that would actually be the behavior I'd expect... I'd want every property of the array object counted, regardless of whether the property also represents an array index. That way it can work for regular objects too. I guess it depends on what behavior you want.
no
On the other hand I'd definitely *not* want cute function properties that someone added to Array.prototype or Object.prototype to show up. Just sayin.
no
@no - Methods can be added directly to an array and not to Array.prototype: http://jsfiddle.net/YHFqJ/ ---- But yeah, it just depends on your view of what an "Array" is... Guess I'm not as open mined as you ;)
Peter Ajtai
@Peter Ajtai: sure, but I'm hoping nobody would ever _do_ that... and if they are, maybe they're adding the same function more than once and they want to see which one occurs the mosst times ;p
no
+1  A: 

If the array is sorted this should work:

function popular(array) { 
   if (array.length == 0) return [null, 0];
   var n = max = 1, maxNum = array[0], pv, cv;

   for(var i = 0; i < array.length; i++, pv = array[i-1], cv = array[i]) {
      if (pv == cv) { 
        if (++n >= max) {
           max = n; maxNum = cv;
        }
      } else n = 1;
   }

   return [maxNum, max];
};

popular([1,2,2,3,4,9,9,9,9,1,1])
[9, 4]

popular([1,2,2,3,4,9,9,9,9,1,1,10,10,10,10,10])
[10, 5]
CD Sanchez
+1  A: 

This version will quit looking when the count exceeds the number of items not yet counted.

It works without sorting the array.

Array.prototype.most= function(){
    var L= this.length, freq= [], unique= [], 
    tem, max= 1, index, count;
    while(L>= max){
        tem= this[--L];
        if(unique.indexOf(tem)== -1){
            unique.push(tem);
            index= -1, count= 0;
            while((index= this.indexOf(tem, index+1))!= -1){
                ++count;
            }
            if(count> max){
                freq= [tem];
                max= count;
            }
            else if(count== max) freq.push(tem);
        }
    }
    return [freq, max];
}

    //test
    var A= ["apples","oranges","oranges","oranges","bananas",
   "bananas","oranges","bananas"];
    alert(A.most()) // [oranges,4]

    A.push("bananas");
    alert(A.most()) // [bananas,oranges,4]
kennebec
-1 for messing with _mine and everybody else's_ copy of `Array`. If I was a supreme creator of a universe, I would have people that pissed me off spend eternity working on projects with programmers that pull crap like this.
aaronasterling
A: 
<?php
$res=mysql_query("select * FROM `check`");
while($row=mysql_fetch_array($res)){
$input[]=$row['value'];
}
# returns most common value in input array
function array_most_common($input)
{
  $counted = array_count_values($input);
  arsort($counted);
  return(key($counted));    
} 
?>
pusp
When someone down-votes, she could let a message at least...
ring0
I did not downvote this answer. But I think it's pretty clear that this got downvoted for multiple reasons; 1) Question is about javascript, answer is in PHP. 2) Question has values stored in an array, answer pulls from a database 3) Given #2, why not use the database for sorting? WTF?
Asaph
A: 

If you have really large data, you may need something like the count-min sketch.

Jouni K. Seppänen