Javascript 计算数组元素的出现次数/频率
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5667888/
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
Counting the occurrences / frequency of array elements
提问by Hyman W
In Javascript, I'm trying to take an initial array of number values and count the elements inside it. Ideally, the result would be two new arrays, the first specifying each unique element, and the second containing the number of times each element occurs. However, I'm open to suggestions on the format of the output.
在 Javascript 中,我试图获取一个初始数值数组并计算其中的元素。理想情况下,结果将是两个新数组,第一个指定每个唯一元素,第二个包含每个元素出现的次数。但是,我愿意接受有关输出格式的建议。
For example, if the initial array was:
例如,如果初始数组是:
5, 5, 5, 2, 2, 2, 2, 2, 9, 4
Then two new arrays would be created. The first would contain the name of each unique element:
然后将创建两个新数组。第一个将包含每个唯一元素的名称:
5, 2, 9, 4
The second would contain the number of times that element occurred in the initial array:
第二个将包含该元素在初始数组中出现的次数:
3, 5, 1, 1
Because the number 5 occurs three times in the initial array, the number 2 occurs five times and 9 and 4 both appear once.
因为数字 5 在初始数组中出现了 3 次,所以数字 2 出现了 5 次,而 9 和 4 都出现了一次。
I've searched a lot for a solution, but nothing seems to work, and everything I've tried myself has wound up being ridiculously complex. Any help would be appreciated!
我已经搜索了很多解决方案,但似乎没有任何效果,而且我自己尝试过的一切都变得异常复杂。任何帮助,将不胜感激!
Thanks :)
谢谢 :)
采纳答案by ?ime Vidas
Here you go:
干得好:
function foo(arr) {
var a = [], b = [], prev;
arr.sort();
for ( var i = 0; i < arr.length; i++ ) {
if ( arr[i] !== prev ) {
a.push(arr[i]);
b.push(1);
} else {
b[b.length-1]++;
}
prev = arr[i];
}
return [a, b];
}
Live demo:http://jsfiddle.net/simevidas/bnACW/
现场演示:http : //jsfiddle.net/simevidas/bnACW/
Note
This changes the order of the original input array using
Array.sort
笔记
这会使用以下方法更改原始输入数组的顺序
Array.sort
回答by typeof
You can use an object to hold the results:
您可以使用一个对象来保存结果:
var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var counts = {};
for (var i = 0; i < arr.length; i++) {
var num = arr[i];
counts[num] = counts[num] ? counts[num] + 1 : 1;
}
console.log(counts[5], counts[2], counts[9], counts[4]);
So, now your counts object can tell you what the count is for a particular number:
因此,现在您的 counts 对象可以告诉您特定数字的计数是多少:
console.log(counts[5]); // logs '3'
If you want to get an array of members, just use the keys()
functions
如果要获取成员数组,只需使用keys()
函数
keys(counts); // returns ["5", "2", "9", "4"]
回答by adamse
var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4].reduce(function (acc, curr) {
if (typeof acc[curr] == 'undefined') {
acc[curr] = 1;
} else {
acc[curr] += 1;
}
return acc;
}, {});
// a == {2: 5, 4: 1, 5: 3, 9: 1}
回答by radicand
If using underscore or lodash, this is the simplest thing to do:
如果使用下划线或 lodash,这是最简单的方法:
_.countBy(array);
Such that:
这样:
_.countBy([5, 5, 5, 2, 2, 2, 2, 2, 9, 4])
=> Object {2: 5, 4: 1, 5: 3, 9: 1}
As pointed out by others, you can then execute the _.keys()
and _.values()
functions on the result to get just the unique numbers, and their occurrences, respectively. But in my experience, the original object is much easier to deal with.
正如其他人所指出的,然后您可以对结果执行_.keys()
和_.values()
函数以分别获取唯一数字及其出现次数。但以我的经验,原始对象要容易得多。
回答by mu is too short
Don't use two arrays for the result, use an object:
不要使用两个数组作为结果,使用一个对象:
a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
result = { };
for(var i = 0; i < a.length; ++i) {
if(!result[a[i]])
result[a[i]] = 0;
++result[a[i]];
}
Then result
will look like:
然后result
看起来像:
{
2: 5,
4: 1,
5: 3,
9: 1
}
回答by Emissary
How about an ECMAScript2015 option.
ECMAScript2015 选项怎么样。
const a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
const aCount = new Map([...new Set(a)].map(
x => [x, a.filter(y => y === x).length]
));
aCount.get(5) // 3
aCount.get(2) // 5
aCount.get(9) // 1
aCount.get(4) // 1
This example passes the input array to the Set
constructor creating a collection of uniquevalues. The spread syntaxthen expands these values into a new array so we can call map
and translate this into a two-dimensional array of [value, count]
pairs - i.e. the following structure:
此示例将输入数组传递给Set
构造函数,以创建唯一值的集合。该价差语法则扩展了这些值到一个新的数组,所以我们可以调用map
并转化为一个二维数组这[value, count]
对-即结构如下:
Array [
[5, 3],
[2, 5],
[9, 1],
[4, 1]
]
The new array is then passed to the Map
constructor resulting in an iterableobject:
Map {
5 => 3,
2 => 5,
9 => 1,
4 => 1
}
The great thing about a Map
object is that it preserves data-types - that is to say aCount.get(5)
will return 3
but aCount.get("5")
will return undefined
. It also allows for anyvalue / type to act as a key meaning this solution will also work with an array of objects.
一个Map
对象的伟大之处在于它保留了数据类型——也就是说aCount.get(5)
会返回3
但aCount.get("5")
会返回undefined
。它还允许任何值/类型充当键,这意味着该解决方案也适用于对象数组。
function frequencies(/* {Array} */ a){
return new Map([...new Set(a)].map(
x => [x, a.filter(y => y === x).length]
));
}
let foo = { value: 'foo' },
bar = { value: 'bar' },
baz = { value: 'baz' };
let aNumbers = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4],
aObjects = [foo, bar, foo, foo, baz, bar];
frequencies(aNumbers).forEach((val, key) => console.log(key + ': ' + val));
frequencies(aObjects).forEach((val, key) => console.log(key.value + ': ' + val));
回答by Dmytro Kozlovskyi
I think this is the simplest way how to count occurrences with same value in array.
我认为这是如何计算数组中具有相同值的出现次数的最简单方法。
var a = [true, false, false, false];
a.filter(function(value){
return value === false;
}).length
回答by corashina
One line ES6 solution. So many answers using object as a map but I can't see anyone using an actual Map
一行 ES6 解决方案。使用对象作为地图的许多答案,但我看不到任何人使用实际地图
const map = arr.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map());
Use map.keys()
to get unique elements
使用map.keys()
获得独特的元素
Use map.values()
to get the occurrences
使用map.values()
来获取事件
Use map.entries()
to get the pairs [element, frequency]
使用map.entries()
以获得对[元件,频率]
var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]
const map = arr.reduce((acc, e) => acc.set(e, (acc.get(e) || 0) + 1), new Map());
console.info([...map.keys()])
console.info([...map.values()])
console.info([...map.entries()])
回答by Vlad Bezden
const data = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]
function count(arr) {
return arr.reduce((prev, curr) => (prev[curr] = ++prev[curr] || 1, prev), {})
}
console.log(count(data))
回答by rjalfa
If you favour a single liner.
如果您喜欢单班轮。
arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});
arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});
Edit (6/12/2015): The Explanation from the inside out. countMap is a map that maps a word with its frequency, which we can see the anonymous function. What reduce does is apply the function with arguments as all the array elements and countMap being passed as the return value of the last function call. The last parameter ({}) is the default value of countMap for the first function call.
编辑 (6/12/2015):由内而外的解释。countMap 是一个将单词与其频率进行映射的映射,我们可以看到匿名函数。reduce 所做的是应用带有参数的函数作为所有数组元素,并将 countMap 作为最后一个函数调用的返回值传递。最后一个参数 ({}) 是第一次函数调用时 countMap 的默认值。