
本文介绍如何遍历包含多个字符串数组的对象,准确统计目标字符串在所有数组中出现的总次数,并提供传统 for 循环与现代函数式方法(reduce + filter)两种高效实现方案。
在实际开发中,我们常遇到结构类似 { key: string[], ... } 的嵌套对象,例如按人员分组的音乐节参与记录。若需统计某个特定值(如 'Benicassim')在整个数据集中出现的总频次,仅用单层循环是不够的——因为 festivals[festival] 是一个数组,而 === 无法直接将数组与字符串比较。
下面以 festivals 对象为例,展示两种专业、健壮且可复用的解决方案:
✅ 方案一:双重 for 循环(清晰易懂,兼容性最佳)
const festivals = {
'Danny': ['Glastonbury','Glastonbury','Leeds','Leeds','Leeds','Benicassim','MadCool'],
'Jimbo': ['Glastonbury','Glastonbury','Leeds','Leeds','Leeds','Leeds','Benicassim','MadCool'],
'Richard': ['Glastonbury','Leeds','Leeds','Benicassim','MadCool'],
'John': ['Glastonbury','Leeds']
};
const target = 'Benicassim';
let totalFestivals = 0;
for (const person in festivals) {
const festivalsList = festivals[person];
for (const fest of festivalsList) {
if (fest === target) {
totalFestivals++;
}
}
}
console.log(totalFestivals); // 输出:3✅ 优点:逻辑直观,无依赖,适用于所有 ES5+ 环境; ⚠️ 注意:确保 person 是对象自身属性(可加 hasOwnProperty 判断,或改用 Object.keys() 更安全)。
✅ 方案二:函数式链式调用(简洁、声明式、推荐用于现代项目)
const target = 'Benicassim';
const totalFestivals = Object.entries(festivals).reduce(
(sum, [_, festivalsArray]) =>
sum + festivalsArray.filter(fest => fest === target).length,
0
);
console.log(totalFestivals); // 输出:3该写法分三步完成:
- Object.entries() 将对象转为 [key, value] 键值对数组;
- reduce() 累计每个数组中匹配项的数量;
- filter(...).length 高效统计当前数组内 target 出现次数(也可替换为 flat().filter(...).length,但会创建中间扁平数组,性能略低)。
✅ 优势:代码更紧凑,不可变、无副作用,便于测试与组合;
? 扩展提示:如需不区分大小写匹配,可改为 fest.toLowerCase() === target.toLowerCase();若需子串匹配(如包含 'Leed'),则用 fest.includes(target)。
? 总结建议
- 初学者或需支持老旧环境时,优先使用双重 for 循环;
- 在现代 TypeScript/ES2015+ 项目中,推荐采用Object.entries + reduce + filter 组合,语义清晰、易于维护;
- 避免常见错误:切勿直接比较 array === string;始终确保内层循环遍历数组元素;
- 进阶场景(如深层嵌套、混合类型),可封装为通用递归计数函数,但本例中结构明确,无需过度设计。
通过以上任一方法,你都能精准、高效地完成跨数组的字符串频次统计任务。










