Search code examples
javascriptarrayssorting

Sort a Javascript Array by frequency and then filter repeats


What is an elegant way to take a javascript array, order by the frequency of the values, and then filter for uniques?

So,

["apples", "oranges", "oranges", "oranges", "bananas", "bananas", "oranges"]

becomes

["oranges, "bananas", "apples"]


Solution

  • Compute the frequency of each item first.

    {
        apples: 1,
        oranges: 4,
        bananas: 2
    }
    

    Then create an array from this frequency object which will also remove the duplicates.

    ["apples", "oranges", "bananas"]
    

    Now sort this array in descending order using the frequency map we created earlier.

    function compareFrequency(a, b) {
        return frequency[b] - frequency[a];
    }
    
    array.sort(compareFrequency);
    

    Here's the entire source (using the newly introduced Array functions in ECMA 5) and combining the de-duplication and frequency map generation steps,

    function sortByFrequency(array) {
        var frequency = {};
    
        array.forEach(function(value) { frequency[value] = 0; });
    
        var uniques = array.filter(function(value) {
            return ++frequency[value] == 1;
        });
    
        return uniques.sort(function(a, b) {
            return frequency[b] - frequency[a];
        });
    }
    

    Same as above using the regular array iteration.

    function sortByFrequencyAndRemoveDuplicates(array) {
        var frequency = {}, value;
    
        // compute frequencies of each value
        for(var i = 0; i < array.length; i++) {
            value = array[i];
            if(value in frequency) {
                frequency[value]++;
            }
            else {
                frequency[value] = 1;
            }
        }
    
        // make array from the frequency object to de-duplicate
        var uniques = [];
        for(value in frequency) {
            uniques.push(value);
        }
    
        // sort the uniques array in descending order by frequency
        function compareFrequency(a, b) {
            return frequency[b] - frequency[a];
        }
    
        return uniques.sort(compareFrequency);
    }