-2

Write a program to find count of the most frequent item of an array. Assume that input is array of integers.

Example:

Input array: [3, -1, -1, -1, 2, 3, -1, 3, -1, 2, 4, 9, 3]

Ouptut: 5

Most frequent number in example array is -1. It occurs 5 times in input array.

Here is my code:

function mostFrequentItemCount(collection) {

  var copy = collection.slice(0);

  for (var i = 0; i < collection.length; i++) {
    var output = 0;
    for (var x = 0; x < copy.length; x++) {
      if (collection[i] == copy[x]) {
        output++; 
      }
    }
  }
  return output; 
}

It seems to be just counting the reoccurrence of the first number in the array not the one that occurs the most. I can't figure out how to make it count the most occurring one.

BSMP
  • 4,596
  • 8
  • 33
  • 44
  • You don't seem to be doing anything that would allow you to compare each unique integer's count to the others to get the one that's largest. – Kevin B May 24 '17 at 22:20
  • not only that, but you're returning the counting variable `output`, not the number whose individual count (which you don't happen to even be collecting) is the highest. – Alnitak May 24 '17 at 22:21
  • A reduce would be the simplest way to solve this (there's an example on MDN that would give you an object with a key for each integer that contains a count... which gets you most of the way to a solution) – Kevin B May 24 '17 at 22:22
  • possible duplicate of https://stackoverflow.com/questions/3783950/get-the-item-that-appears-the-most-times-in-an-array – The_Outsider May 24 '17 at 22:28

5 Answers5

1

If i didn't miss anything, and if you really want to find the count of the most frequent item of an array, i guess one approach would be this one:

function existsInCollection(item, collection) {
    for(var i = 0; i < collection.length; i++) {
        if(collection[i] === item) {
            return true;
        }
    }
    
    return false;
}

function mostFrequentItemCount(collection) {
        var most_frequent_count = 0;
        var item_count = 0;
        var already_checked = [];
        
        for(var i = 0; i < collection.length; i++) {
            // if the item was already checked, passes to the next
            if(existsInCollection(collection[i], already_checked)) {
                continue;
            } else {
                // if it doesn't, adds to the already_checked list
                already_checked.push(collection[i]);
            }
            
            for(var j = 0; j < collection.length; j++)
                if(collection[j] === collection[i])
                    item_count++;

            if(item_count > most_frequent_count)
                most_frequent_count = item_count;

            item_count = 0;

        }

        return most_frequent_count;
    }
    
    var items = [3, -1, -1, -1, 2, 3, -1, 3, -1, 2, 4, 9, 3];
    
    alert(mostFrequentItemCount(items));

What happens here is:

On each item ('i' loop), it will run another loop ('j') through all items, and count how many are equal to the [i] item. After this second loop, it will be verified if that item count is greater than the most_frequent_count that we already have, and if it is, updates it. Since we always use the same variable 'item_count' to check each number count, after the verification of each number we reset it to 0.

This may not be the best answer, but it was what occurred me at the moment.

EDIT: I added a function to check if an item already exists in a list, to avoid the loop from check the same item again.

pauloaap
  • 828
  • 6
  • 11
  • 2
    Thank you. This is what I was looking for. Can you explain to me how the most_frequent_count variable is working? – Ashley Brown May 24 '17 at 23:04
  • Sure. I edited the post and added an explanation right now :). The 'most_frequent_count' variable is used just to save the higher frequency that we get on each loop. – pauloaap May 24 '17 at 23:08
0

The problem is that you override the output variable each loop iteration, so after the for loop ends your output variable holds occurrences of the last element of input array.

You should use variables like var best_element = collection[0] and var best_element_count = -1 (initialized like this). After each inner loop you check if algo found any better solution (best_element_count < output) and update best_element.

Edit: following @Alnitak comment you should also reset the output variable after each inner loop iteration.

Jakub Licznerski
  • 1,008
  • 1
  • 17
  • 33
0

First you will need to construct a collection (or object) that contains the element and the count of occurances. Second you will need to iterate the result to find the key that has the highest value.

JSFiddle

function mostFrequentItemCount(collection) {
  var output = {};
  for (var i = 0; i < collection.length; i++) {
    var item = collection[i];
    if (!(item in output))
      output[item] = 0;
    output[item]++;
  }
  var result = [0, 5e-324];
  for (var item in output) {
    if (output[item] > result[1]) {
      result[0] = parseFloat(item);
      result[1] = output[item];
    }
  }
  return result;
}
var input = [3, -1, -1, -1, 2, 3, -1, 3, -1, 2, 4, 9, 3];
var result = mostFrequentItemCount(input);
console.log(result);

The snippet above simply creates a new object (output) which contains a property for each of the unique elements in the array. The result is something like.

2:2
3:4
4:1
9:1
-1:5

So now we have an object with the property for the number and the value for the occurances. Next we then interate through each of the properties in the output for(var item in output) and determine which value is the greatest.

Now this returns an array with the value at index 0 being the number and the value at index 1 being the count of the element.

Nico
  • 12,493
  • 5
  • 42
  • 62
0

Check this solution.

var store = [3, -1, -1, -1, 2, 3, -1, 3, -1, 2, 4, 9, 3];
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.
        }
}
alert(max);
TheFallenOne
  • 1,598
  • 2
  • 23
  • 57
-1

So this update to your method will return an object with each key and the count for that key in the array. How you format an output to say what key has what count is up to you.

Edit: Updated to include the complete solution to the problem.

function mostFrequentItemCount(collection) {
  var copy = collection.slice(0);
  var results = {};
  for (var i = 0; i < collection.length; i++) {
    var count = 0;
    for (var x = 0; x < copy.length; x++) {
      if (collection[i] == copy[x]) {
        count++; 
      }
    }
    results[collection[i]] = count;
  }
  
  return results; 
}

var inputArray = [3, -1, -1, -1, 2, 3, -1, 3, -1, 2, 4, 9, 3];
var occurances = mostFrequentItemCount(inputArray);
var keyWithHighestOccurance = Object.keys(occurances).reduce(function(a, b){ return occurances[a] > occurances[b] ? a : b });
var highestOccurance = occurances[keyWithHighestOccurance];
console.log("Most frequent number in example array is " + keyWithHighestOccurance + ". It occurs " + highestOccurance + " times in the input array.");
Ken
  • 466
  • 2
  • 7