
本文介绍如何将包含姓名和类别(如 ['jack', 'a'])的二维数组,按姓名→类别两级结构进行分组并统计频次,最终生成嵌套对象,并可进一步格式化为易读的键值对列表。
本文介绍如何将包含姓名和类别(如 ['jack', 'a'])的二维数组,按姓名→类别两级结构进行分组并统计频次,最终生成嵌套对象,并可进一步格式化为易读的键值对列表。
在 JavaScript 中,对二维数组按多个维度(如“人名”和“标签”)进行分组计数,本质是构建一个嵌套哈希表(即对象嵌套对象),而非简单地将整个子数组作为键(因为数组无法直接用作对象属性名,且 counts[element] 会将 ['Jack','A'] 转为字符串 "Jack,A",导致语义丢失和后续处理困难)。
以下是实现该需求的专业解决方案:
✅ 正确思路:两级嵌套对象计数
const array = [
['Jack', 'A'], ['Jack', 'A'], ['Sara', 'A'],
['Jack', 'B'], ['Peter', 'B'], ['Sara', 'C'],
['Sara', 'B'], ['Sara', 'A'], ['Sara', 'B'],
['Peter', 'B'], ['Peter', 'A'], ['Peter', 'C']
];
function groupAndCount(arr) {
const result = {};
for (const [name, category] of arr) {
// 确保 name 层存在
if (!result[name]) result[name] = {};
// 确保 category 层存在并累加
result[name][category] = (result[name][category] || 0) + 1;
}
return result;
}
const grouped = groupAndCount(array);
console.log(grouped);
// 输出:
// {
// Jack: { A: 2, B: 1 },
// Sara: { A: 2, B: 2, C: 1 },
// Peter: { B: 2, A: 1, C: 1 }
// }
? 进阶:格式化为指定字符串输出(如 "Jack: A : 2")
若需按题目要求输出扁平化的字符串列表,可遍历嵌套结果:
function formatGroupedResult(grouped) {
const lines = [];
for (const [name, categories] of Object.entries(grouped)) {
for (const [category, count] of Object.entries(categories)) {
lines.push(`${name}: ${category} : ${count}`);
}
}
return lines.sort(); // 可选:按字母序排序增强可读性
}
console.log(formatGroupedResult(grouped).join('\n'));
// 输出(排序后):
// Jack: A : 2
// Jack: B : 1
// Peter: A : 1
// Peter: B : 2
// Peter: C : 1
// Sara: A : 2
// Sara: B : 2
// Sara: C : 1
⚠️ 注意事项
- ❌ 避免
counts[element]写法:element是数组,直接用作对象键会触发toString(),变成"Jack,A",丧失结构信息,且无法区分['Jack','A']和['Jack,A'](后者为单元素数组)。 - ✅ 推荐解构赋值
const [name, category] of arr,语义清晰、兼容性好(ES6+)。 - ✅ 使用
Object.entries()遍历嵌套对象,确保顺序可控;如需严格顺序,建议配合sort()或使用Map(但本例中普通对象已足够)。 - ? 若数据量极大(>10万项),可考虑
Map提升性能,但日常业务场景中对象完全胜任。
该方法简洁、健壮、易于扩展(如增加第三级分组),是处理多维分类统计的通用范式。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











