Сортировать массив Javascript по частоте, а затем фильтр повторяется

Каков элегантный способ взять массив javascript, упорядочить по частоте значений и затем отфильтровать по уникальным?

Итак,

["яблоки", "апельсины", "апельсины", "апельсины", "бананы", "бананы", "апельсины"]

становится

["апельсины," бананы "," яблоки "]

16
задан Yahel 26 August 2010 в 21:52
поделиться

5 ответов

Сначала вычислите частоту каждого элемента.

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

Затем создайте массив из этого частотного объекта, который также удалит дубликаты.

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

Теперь отсортируйте этот массив в порядке убывания, используя карту частот, которую мы создали ранее.

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

array.sort(compareFrequency);

Вот весь исходный код (с использованием недавно введенных функций массива в ECMA 5) и объединение шагов дедупликации и генерации частотной карты,

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];
    });
}

То же, что и выше, с использованием обычной итерации массива.

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);
}
28
ответ дан 30 November 2019 в 16:24
поделиться
var arr = ["apples", "oranges", "oranges", "oranges", "bananas", "bananas", "oranges"].sort();
var freq = {};
for (var s in arr) freq[s] = freq[s] ? freq[s] + 1 : 0;
arr.sort(function(a, b) { return freq[a] > freq[b] ? -1 : 1; });
for (var i = arr.length - 1; i > 0; i--) if (arr[i] == arr[i - 1]) arr.splice(i,1);
alert(arr.join(","));
1
ответ дан 30 November 2019 в 16:24
поделиться

// возвращает наиболее частый в наименее частый

Array.prototype.byCount= function(){
    var itm, a= [], L= this.length, o= {};
    for(var i= 0; i<L; i++){
        itm= this[i];
        if(!itm) continue;
        if(o[itm]== undefined) o[itm]= 1;
        else ++o[itm];
    }
    for(var p in o) a[a.length]= p;
    return a.sort(function(a, b){
        return o[b]-o[a];
    });
}

//тест

var A= ["apples","oranges","oranges","oranges","bananas","bananas","oranges"];
A.byCount()

/* возвращаемое значение: (массив) апельсины, бананы, яблоки */

5
ответ дан 30 November 2019 в 16:24
поделиться

Основная стратегия:

Создайте объект для использования в качестве хэш-таблицы для отслеживания частоты появления каждого элемента в сортируемом массиве.

Создайте новый массив, содержащий пары элементов и частот.

Отсортируйте этот массив по частоте в порядке убывания.

Извлеките элементы из этого массива.

Код:

function descendingUniqueSort(toBeSorted) {
    var hash = new Object();
    toBeSorted.forEach(function (element, index, array) { 
                           if (hash[element] == undefined) {
                               hash[element] = 1;
                           }
                           else {
                               hash[element] +=1;
                           }});
    var itemCounts = new Array();
    for (var key in hash) {
       var itemCount = new Object();
       itemCount.key = key;
       itemCount.count = hash[key];
       itemCounts.push(itemCount);
    }
    itemCounts.sort(function(a,b) { if(a.count<b.count) return 1; 
        else if (a.count>b.count) return -1; else return 0;});

    return itemCounts.map(function(itemCount) { return itemCount.key; });
 }
1
ответ дан 30 November 2019 в 16:24
поделиться

На самом деле я работал над этим в то же время - решение, которое я придумал, в значительной степени идентично решению Анурага.

Однако я подумал, что, возможно, стоит поделиться, так как у меня был немного другой способ вычисления частоты вхождений, используя тернарный оператор и проверяя, было ли значение подсчитано немного другим способом.

function sortByFrequencyAndFilter(myArray)
{
    var newArray = [];
    var freq = {};

    //Count Frequency of Occurances
    var i=myArray.length-1;
    for (var i;i>-1;i--)
    {
        var value = myArray[i];
        freq[value]==null?freq[value]=1:freq[value]++;
    }

    //Create Array of Filtered Values
    for (var value in freq)
    {
        newArray.push(value);
    }

    //Define Sort Function and Return Sorted Results
    function compareFreq(a,b)
    {
        return freq[b]-freq[a];
    }

    return newArray.sort(compareFreq);
}
2
ответ дан 30 November 2019 в 16:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: