2010-08-26 122 views

回答

22

计算每个项目的频率第一。

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

然后从这个频率对象中创建一个数组,它也将删除重复项。

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

现在使用我们之前创建的频率图降序排列这个数组。

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

array.sort(compareFrequency); 

这里的整个源(使用新引入Array functions在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); 
} 
+0

可能是值得缓存array.length代替检查每个迭代 – second 2010-08-26 21:40:52

+1

@second - 对于大型数据集来说,这是一个很好的优化。有些浏览器可能已经在内部执行此操作。 – Anurag 2010-08-26 21:45:28

+0

这可能是你会发现的优雅。 – palswim 2010-08-26 21:46:18

1

基本策略:

创建一个对象使用作为哈希表来跟踪每个项目的频率数组中进行排序。

创建一个包含项目,频率对的新数组。

按降序对这个数组进行频率排序。

从该数组中提取项目。

代码:

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

我其实在做这个的同时 - 我想出了解决的办法是几乎相同阿努拉格的。

然而,我认为这可能是值得分享的,因为我使用三元运算符计算出现频率的方法略有不同,并且检查值是否以稍微不同的方式计算。

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

我用来计算出现频率的循环是针对一个常量值进行检查,并以相反的顺序遍历数组。这对大型阵列来说也会更快。 – John 2010-08-26 22:00:00

5

//返回最频繁到最不频繁的

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() 

/*返回的值:(阵列) 橙子,香蕉,苹果 */

+1

如果这是代码高尔夫比赛,你应该赢了! – palswim 2010-08-26 22:15:07

+0

真的很欣赏这一个。修改它出dict与字典参考字典[术语],谢谢你。大大的帮助,正是我所需要的 – twobob 2017-05-05 20:50:02

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

的第一步计算

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

可以使用underscroe.js

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

的countBy功能,使frequency对象将包含所有唯一值的频率,并且你可以通过简单地得到一个唯一列表调用_.uniq(all),和下划线的_.sortBy方法那种独特的列表,并使用您的frequency对象,你可以使用

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

-ve此处使用符号按照您的要求通过频率值以降序排列列表。

您可以通过自己的绝招检查进一步优化了的http://underscorejs.org/文档:)

0

对于ES6,只需用.filter代码和.sort如下

> 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"] 
相关问题