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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:22:11  来源:igfitidea点击:

Counting the occurrences / frequency of array elements

javascriptarrayscountelement

提问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 resultwill 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 Setconstructor creating a collection of uniquevalues. The spread syntaxthen expands these values into a new array so we can call mapand 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 Mapconstructor resulting in an iterableobject:

然后将新数组传递给Map构造函数,生成一个可迭代对象:

Map {
    5 => 3,
    2 => 5,
    9 => 1,
    4 => 1
}

The great thing about a Mapobject is that it preserves data-types - that is to say aCount.get(5)will return 3but 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)会返回3aCount.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 的默认值。