什麼是採用javascript數組,按值的頻率排序,然後篩選唯一身份的優雅方法?按頻率對Javascript Array進行排序,然後重複篩選
所以,
["apples", "oranges", "oranges", "oranges", "bananas", "bananas", "oranges"]
變得
["oranges, "bananas", "apples"]
什麼是採用javascript數組,按值的頻率排序,然後篩選唯一身份的優雅方法?按頻率對Javascript Array進行排序,然後重複篩選
所以,
["apples", "oranges", "oranges", "oranges", "bananas", "bananas", "oranges"]
變得
["oranges, "bananas", "apples"]
計算每個項目的頻率第一。
{
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);
}
基本策略:
創建一個對象使用作爲哈希表來跟蹤每個項目的頻率數組中進行排序。
創建一個包含項目,頻率對的新數組。
按降序對這個數組進行頻率排序。
從該數組中提取項目。
代碼:
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; });
}
我其實在做這個的同時 - 我想出瞭解決的辦法是幾乎相同阿努拉格的。
然而,我認爲這可能是值得分享的,因爲我使用三元運算符計算出現頻率的方法略有不同,並且檢查值是否以稍微不同的方式計算。
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);
}
我用來計算出現頻率的循環是針對一個常量值進行檢查,並以相反的順序遍歷數組。這對大型陣列來說也會更快。 – John 2010-08-26 22:00:00
//返回最頻繁到最不頻繁的
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()
/*返回的值:(陣列) 橙子,香蕉,蘋果 */
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(","));
的第一步計算
{
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/文檔:)
對於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"]
可能是值得緩存array.length代替檢查每個迭代 – second 2010-08-26 21:40:52
@second - 對於大型數據集來說,這是一個很好的優化。有些瀏覽器可能已經在內部執行此操作。 – Anurag 2010-08-26 21:45:28
這可能是你會發現的優雅。 – palswim 2010-08-26 21:46:18