1

Suppose I have an array with n elements, some of which may occur more than once.

I want to select the top m elements that occur most often in that array.

Can anybody help me with that?

For example, suppose the array is [1, 3, 2, 3, 5, 2, 2, 3, 6, 8, 9] with n=11 elements. If I want to select the top m=2 of them, those would be 2 and 3.

What would be the best script to do that?

2
  • 1
    Make an array of { value: n, count: c } objects. Sort them by count. Then take the first m elements. Commented Dec 27, 2014 at 12:58
  • 2
    What if the result is tied for more than the number you asked for? (E.g. m=3 for your sample array.) Commented Dec 27, 2014 at 13:00

2 Answers 2

2

You could create a temporary object to hold the occurrences like key: count. Then use the array returned by Object.keys to sort the object values. Then slice the last "n" elements from that array in .reverse() order.

Here is an example utility function to get top "n" max occurrences. Note: As @n6 stated above in the comments, this ignores the ties.

Demo fiddle: https://jsfiddle.net/abhitalks/s43k6vsq/

Snippet:

var data1 = [1, 3, 2, 3, 5, 2, 2, 3, 6, 8, 9], 
    data2 = [4, 4, 4, 2, 2, 1, 5, 5, 8, 8, 8, 8, 3], 
    data3 = [3, 23, 23, 45, 54, 54, 54];

// Function parameters = Data Array and top "n" elements to find
function getMax(data, n) {
    var tmp = {}, tops = [];
  
    // Create object with count of occurances of each array element
    data.forEach(function(item) {
        tmp[item] = tmp[item] ? tmp[item]+1 : 1;
    });
  
    // Create an array of the sorted object properties
    tops = Object.keys(tmp).sort(function(a, b) { return tmp[a] - tmp[b] });
  
    // Return last n elements in reverse order
    return tops.slice(-(n)).reverse();
}

// Test with sample data and top "n" 
console.log(getMax(data1, 2));
console.log(getMax(data2, 3));
console.log(getMax(data3, 1));

Sign up to request clarification or add additional context in comments.

Comments

1

a solution:

var arr = [1,2,3,41,11,2,3,4,1];
var sorted = [];

for (var i = 0; i < arr.length; i++) {
    var index = -1;

    for (var j = 0; j < sorted.length; j++) {
        if (sorted[j].val == arr[i]) index = j;
    }

    if (index == -1) {
        sorted.push({val: arr[i], count: 1})
    }

    else {
        sorted[index].count++;
    }

}

console.log(sorted.sort(function(a,b){

if (a.count > b.count) return -1;

if (a.count < b.count) return 1

    return 0

})[0])

FIDDLE

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.