
本文介绍如何遍历对象并统计其所有属性值的出现次数,返回一个以值为键、频次为值的新对象,适用于数据聚合与频次分析场景。
在实际开发中,我们常需对对象中重复出现的值进行频次统计(例如统计用户选择的标签、接口返回的状态码分布等)。给定一个键值任意的对象,目标是忽略键名,仅按值(value)分组计数,最终生成形如 { a: 3, b: 1, c: 2, d: 1 } 的统计结果。
实现的核心思路是:遍历对象的每个自有可枚举属性,提取其值,并在结果对象中对该值进行累加计数。以下是推荐的简洁高效实现:
function countOccurrences(obj) { const result = {}; for (const key in obj) { // 确保只处理对象自身的属性(非原型链继承) if (Object.prototype.hasOwnProperty.call(obj, key)) { const value = obj[key]; // 若 result[value] 已存在则加 1,否则初始化为 0 再加 1 result[value] = (result[value] ?? 0) + 1; } } return result; }
✅ 使用示例:
const obj1 = { 1: 'a', 2: 'b', 3: 'a', 4: 'c', 5: 'a', 6: 'd', 7: 'c' }; console.log(countOccurrences(obj1)); // 输出: { a: 3, b: 1, c: 2, d: 1 }
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- for…in 会遍历所有可枚举属性(包括继承属性),因此建议配合 hasOwnProperty() 或 Object.keys() 使用以确保健壮性;
- 上述代码使用空值合并操作符 ?? 替代 ||,更安全地处理 falsy 值(如 0、”、false)——若原始对象可能包含这些值作为合法计数目标,推荐此写法;
- 若需支持 symbol 键或不可枚举属性,应改用 Object.getOwnPropertyNames() + Object.getOwnPropertySymbols() 组合遍历;
- 对于超大对象,可考虑使用 map 提升性能(尤其当值为对象或函数时),但本例中字符串键已足够高效。
总结:该方法轻量、兼容性好(支持所有 ES5+ 环境),是对象值频次统计的标准实践方案。