2010-08-26 19 views

Répondre

22

Calculer la fréquence de chaque élément premier. Créez ensuite un tableau à partir de cet objet de fréquence, qui supprimera également les doublons.

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

Maintenant, triez ce tableau dans l'ordre décroissant en utilisant la carte de fréquence que nous avons créée précédemment.

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

array.sort(compareFrequency); 

est ici la source entière (en utilisant le nouvellement introduit Array functions dans ECMA 5) et en combinant les de déduplication et de cartes de fréquence étapes de génération,

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

Comme ci-dessus en utilisant l'itération de réseau régulier.

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); 
} 
+0

vaut peut-être la mise en cache array.length au lieu de vérifier sur chaque itération – second

+1

@second - c'est une bonne optimisation pour les grands ensembles de données. Certains navigateurs peuvent déjà le faire en interne. – Anurag

+0

C'est probablement aussi élégant que vous trouverez. – palswim

1

stratégie de base:

créer un objet à utiliser comme table de hachage pour suivre la fréquence de chaque élément du tableau à trier.

Créez un nouveau tableau contenant l'élément, les paires de fréquences.

Trier ce tableau sur la fréquence dans l'ordre décroissant.

Extrayez les éléments de ce tableau.

code:

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

je travaillais en fait sur ce même temps - de la solution que je suis venu avec est à peu près identique à Anurag.

Cependant, je pensais que ça valait la peine d'être partagé car j'avais une façon légèrement différente de calculer la fréquence des occurrences, en utilisant l'opérateur ternaire et en vérifiant si la valeur avait été comptée légèrement.

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); 
} 
+0

La boucle que j'utilise pour compter la fréquence d'occurrences vérifie une valeur constante et effectue une boucle dans le tableau à l'envers. Cela fonctionnerait également plus rapidement sur les grandes baies. – John

5

// retourne le plus fréquent au moins fréquent

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

// test

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

/* valeur retournée: (Array) oranges, les bananes, les pommes */

+1

Si c'était une compétition de Code Golf, vous auriez gagné! – palswim

+0

Vraiment apprécier celui-ci. L'a modifié pour sortir une dictée avec les comptes référencables par dict [term], merci l'homme. Grande aide, juste ce dont j'avais besoin – twobob

1
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

pour la première étape pour calculer

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

vous pouvez utiliser la fonction countBy de underscroe.js

var all=["apples", "oranges", "oranges", "oranges", "bananas", "bananas", "oranges"]; 
var frequency=_.countBy(all,function(each){return each}); 

si frequency objet contiendra la fréquence de toutes les valeurs uniques, et vous pouvez obtenir une liste unique, simplement appelant _.uniq(all), et de trier cette liste unique, par la méthode de _.sortBy underscore et en utilisant votre objet frequency vous pouvez utiliser

_.sortBy(_.uniq(all),function(frequencyKey){return -frequency[frequencyKey]}); 

-ve Le signe est utilisé ici pour trier la liste dans l'ordre décroissant au moyen de la valeur de fréquence selon vos besoins.

Vous pouvez consulter la documentation de la http://underscorejs.org/ pour une optimisation plus poussée par votre propre truc :)

0

Pour ES6, simplement avec des codes .filter et .sort comme ci-dessous

> var arr = ["apples", "oranges", "oranges", "oranges", "bananas", "bananas", "oranges"]; 
> arr.filter((key, idx) => arr.lastIndexOf(key) === idx).sort((a, b) => a < b ? -1 : 1); 
    ["apples", "bananas", "oranges"] 
Questions connexes