统计每个数组元素的出现次数,并以对象形式返回结果

3

有没有原生的替代方案可以从以下内容开始:

const colorArray = ['red', 'green', 'green', 'blue', 'purple', 'red', 'red', 'black'];

to:

Object {
  "red": 3,
  "green": 2,
  "blue": 1,
  "purple": 1,
  "black": 1
}

在JavaScript中?

const colorArray = ['red', 'green', 'green', 'blue', 'purple', 'red', 'red', 'black'];

function categorizeUnique(array) {
  const distinct_objects = {};
  const length = array.length;
  for(let i=0; i<length; i++) {
    const distinct_objects_keys = Object.keys(distinct_objects);
    const possible_index = distinct_objects_keys.indexOf(array[i]);
    if(possible_index === -1) {
      distinct_objects[array[i]] = 1;
    } else {
      distinct_objects[distinct_objects_keys[possible_index]]++;
    }
  }
  return distinct_objects;
}

const result = categorizeUnique(colorArray);
console.log(result);

That was my try to accomplish this but I'd like a native solution already built in.

感谢您宝贵的时间和努力!
2个回答

6

Array.prototype.reduce() 看起来很接近您所需要的:

const src = ['red', 'green', 'green', 'blue', 'purple', 'red', 'red', 'black'],

      result = src.reduce((acc,color) => (acc[color]=(acc[color]||0)+1, acc), {})
      
console.log(result)
.as-console-wrapper{min-height:100%;}


我并不真正理解 (acc,color) => (acc[color]=(acc[color]||0)+1, acc) 这段代码是如何工作的。顺便说一下,我对 reduce 函数有一些经验,了解累加器和当前参数。请解释一下。 - Jhon
1
@Jhon: 我相信,是短路评估逗号运算符让你感到困惑。 - Yevhen Horbunkov
1
@Jhon: 简而言之,acc[color]||0被解释为当前颜色的累加器:如果前者是“未定义”(在第一次越过每个特定颜色时),则它将被解释为0(acc[color]=(acc[color]||0)+1, acc)实际上与acc[color] = acc[color]||0+1; return acc相同。 - Yevhen Horbunkov
小心使用 逗号运算符 -> 无序列规则 - Ele

2
使用 .reduce 方法:

const colorArray = ['red', 'green', 'green', 'blue', 'purple', 'red', 'red', 'black'];

let colorCount = colorArray.reduce((a, c) => ({ ...a, [c]: a[c] + 1 || 1}), {} );
      
console.log(colorCount);


这种方法的一个小问题是,它在每次迭代时都会不必要地重新创建累加器对象,这可能会在输入数组足够大时减慢代码的执行速度。 - Yevhen Horbunkov

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