JavaScript数组分组

34

可能是重复问题:
JavaScript中的array_count_values替代方法


假设我有一个简单的JavaScript数组,如下所示:

var array = ['Car', 'Car', 'Truck', 'Boat', 'Truck'];

我想对每个分组进行计数,期望得到一个键/值映射:

{
  Car   : 2,
  Truck : 2,
  Boat  : 1
}

3
你有试过一些行不通的事情吗? - haynar
4
我不认为这是重复的。这个问题比PHP的问题更通用。 - Andre Figueiredo
1
我也不认为这是重复的问题。我正在寻找有关JavaScript的问题和答案,我不会理解那个只列出PHP代码的问题。 - Ande
3个回答

60
var arr = [ 'Car', 'Car', 'Truck', 'Boat', 'Truck' ];
var hist = {};
arr.map( function (a) { if (a in hist) hist[a] ++; else hist[a] = 1; } );
console.log(hist);

导致结果为

{ Car: 2, Truck: 2, Boat: 1 }

这也可以运行:

hist = arr.reduce( function (prev, item) { 
  if ( item in prev ) prev[item] ++; 
  else prev[item] = 1; 
  return prev; 
}, {} );

第一种解决方案对于不兼容变量名称的值(如GUID或整数)无效,尽管它很好。 - Kat Lim Ruiz
9
注意,根据 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map,map 方法会创建原数组的一个副本。在您的情况下,您甚至没有使用那个副本,所以最好像这样做:arr.forEach(function (a) { if (a in hist) hist[a] ++; else hist[a] = 1; }),因为 forEach 不会创建新的副本。 - ludo
1
如果您正在使用Underscore,除了arr.reduce之外,您还可以尝试使用_.countBy(list, iterator) http://underscorejs.org/#countBy - Ande
感谢提供使用reduce从数组创建字典的示例。 - blazkovicz
你应该在第一个解决方案中使用 Array.prototype.forEach() 而不是 Array.prototype.map() - Daniel
可以使用 arr.map((a) => a in hist ? hist[a] ++ : hist[a] = 1); 进行整理。 - chri3g91

6
你可以遍历每个索引并将其保存在字典中,当找到该键时递增它。
count = {};
for(a in array){
  if(count[array[a]])count[array[a]]++;
  else count[array[a]]=1;
}

输出结果将是:
Boat: 1
Car: 2
Truck: 2

0
你可以使用JavaScript中的reduce方法来实现所需的输出。reduce方法用于在遍历数组时累积值。以下是如何使用reduce方法对输入数组中的元素进行分组和计数的示例。
let array = ['Car', 'Car', 'Truck', 'Boat', 'Truck'];

let frequencyMap = array.reduce((map, item) => {
  if (!map[item]) {
    map[item] = 1;
  } else {
    map[item]++;
  }
  return map;
}, {});

console.log(frequencyMap);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接