按频率对 Javascript 数组进行排序,然后过滤重复
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3579486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sort a Javascript Array by frequency and then filter repeats
提问by Yahel
What is an elegant way to take a javascript array, order by the frequency of the values, and then filter for uniques?
什么是采用 javascript 数组、按值的频率排序、然后过滤唯一值的优雅方法?
So,
所以,
["apples", "oranges", "oranges", "oranges", "bananas", "bananas", "oranges"]
["apples", "oranges", "oranges", "oranges", "bananas", "bananas", "oranges"]
becomes
变成
["oranges, "bananas", "apples"]
["oranges, "bananas", "apples"]
回答by Anurag
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 functionsin ECMA 5) and combining the de-duplication and frequency map generation steps,
这是整个源代码(使用ECMA 5 中新引入的Array 函数)并结合了重复数据删除和频率图生成步骤,
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);
}
回答by kennebec
// returns most frequent to least frequent
// 返回最频繁到最不频繁
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()
/* returned value: (Array) oranges,bananas,apples */
/* 返回值:(数组)橙子、香蕉、苹果 */
回答by John
I was actually working on this at the same time - the solution I came up with is pretty much identical to Anurag's.
我实际上同时也在研究这个 - 我想出的解决方案与 Anurag 的解决方案几乎相同。
However I thought it might be worth sharing as I had a slightly different way of calculating the frequency of occurrences, using the ternary operator and checking if the value has been counted yet in a slightly different way.
但是,我认为这可能值得分享,因为我计算出现频率的方法略有不同,使用三元运算符并检查值是否已以略有不同的方式计算在内。
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);
}
回答by Minime
Let me put a minimal code to get unique values (and with frequencies) in ES6.
让我用最少的代码在 ES6 中获取唯一值(和频率)。
var arr = ["apples", "oranges", "oranges", "oranges", "bananas", "bananas", "oranges"];
console.log([...new Set(arr)])
It is also applied to array of objects to aggregate some properties.
它还应用于对象数组以聚合某些属性。
var arr = [{"fruit":"apples"}, {"fruit":"oranges"}, {"fruit":"oranges"}, {"fruit":"oranges"}, {"fruit":"bananas"}, {"fruit":"bananas"}, {"fruit":"oranges"}];
console.log(arr.reduce((x,y)=>{if(x[y.fruit]) {x[y.fruit]++;return x;} else {var z={};z[y.fruit]=1;return Object.assign(x,z);}},{}))
回答by ngroot
Basic strategy:
基本策略:
Create an object to use as a hash table to track the frequency of each item in the array to be sorted.
创建一个对象用作哈希表来跟踪要排序的数组中每个项目的频率。
Create a new array containing the item, frequency pairs.
创建一个包含项目、频率对的新数组。
Sort this array on frequency in descending order.
按频率降序对此数组进行排序。
Extract the items from that array.
从该数组中提取项目。
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; });
}
回答by Zafer
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(","));
回答by Koushik Chatterjee
for the first step to compute
第一步计算
{
oranges: 4,
bananas: 2,
apples: 1
}
you can use countBy function of underscroe.js
你可以使用 underscroe.js 的 countBy 函数
var all=["apples", "oranges", "oranges", "oranges", "bananas", "bananas", "oranges"];
var frequency=_.countBy(all,function(each){return each});
so frequencyobject will contain frequency of all unique values, and you can get an unique list by simply calling _.uniq(all), and to sort that unique list by the _.sortBymethod of underscore and using your frequencyobject you can use
所以frequency对象将包含所有唯一值的频率,您可以通过简单地调用来获得一个唯一列表_.uniq(all),并通过_.sortBy下划线和使用您frequency可以使用的对象对该唯一列表进行排序
_.sortBy(_.uniq(all),function(frequencyKey){return -frequency[frequencyKey]});
-vesign is used here to sort the list in decending order by means of frequency value as per your requirement.
-ve此处使用符号根据您的要求通过频率值按降序对列表进行排序。
You can check the the documentation of http://underscorejs.org/for further optimization by your own trick :)
您可以通过自己的技巧检查http://underscorejs.org/的文档以进一步优化:)
回答by zangw
For ES6, simply codes with .filterand .sortas below
对于 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"]

