如何用reduce方法将字符串数组转为指定格式的频率统计数组?
字符串频率统计格式修正
需求
将给定字符串数组中每个字符串及其出现频率,以{string: '字符串', frequency: 次数}的对象形式存储在数组中,仅使用reduce方法实现。
现有代码
const strings = ["pink", "red", "pink", "yellow", "yellow", "yellow"]; const frequencyOfStrings = (arrayOfStrings) => { return arrayOfStrings.reduce((acc, curr) => { if (acc[curr]) { acc[curr]++; } else { acc[curr] = 1; } return acc; }, []); }; console.log(frequencyOfStrings(strings));
当前输出
[ pink: 2, red: 1, yellow: 3 ]
期望输出
[{ string: 'pink', frequency: 2 }, { string: 'red', frequency: 1 }, { string: 'yellow', frequency: 3 }]
修改方案
你当前代码的问题在于初始累加器用了数组[],实际是在给数组添加自定义属性,得到的是带额外属性的数组,而非目标格式。这里提供两种仅用reduce的实现方式:
方式一:分两次reduce(逻辑清晰,效率更高)
const strings = ["pink", "red", "pink", "yellow", "yellow", "yellow"]; const frequencyOfStrings = (arrayOfStrings) => { // 第一步:用reduce统计每个字符串的出现次数,得到统计对象 const countObj = arrayOfStrings.reduce((acc, curr) => { // 简化写法:已存在则加1,不存在则初始化为1 acc[curr] = (acc[curr] || 0) + 1; return acc; }, {}); // 第二步:将统计对象转成目标格式的数组 return Object.entries(countObj).reduce((acc, [str, freq]) => { acc.push({ string: str, frequency: freq }); return acc; }, []); }; console.log(frequencyOfStrings(strings));
代码说明
- 第一次reduce:初始值用空对象
{},遍历数组时更新每个字符串的计数,最终得到{pink:2, red:1, yellow:3}的统计对象。 Object.entries(countObj)会把统计对象转换为[['pink',2], ['red',1], ['yellow',3]]的键值对数组。- 第二次reduce:初始值用空数组
[],把每个键值对转换成目标格式的对象并加入数组。
方式二:单次reduce实现(直观但效率稍低)
const strings = ["pink", "red", "pink", "yellow", "yellow", "yellow"]; const frequencyOfStrings = (arrayOfStrings) => { return arrayOfStrings.reduce((acc, curr) => { // 在累加器数组中查找当前字符串对应的对象 const existingItem = acc.find(item => item.string === curr); if (existingItem) { // 找到则更新频率 existingItem.frequency++; } else { // 没找到则新增对象 acc.push({ string: curr, frequency: 1 }); } return acc; }, []); }; console.log(frequencyOfStrings(strings));
代码说明
直接在目标数组中维护格式对象,每次遍历检查当前字符串是否已存在,存在则更新频率,不存在则新增对象。这种写法更直观,但find方法会遍历数组,大数据量下效率不如第一种方式。
内容的提问来源于stack exchange,提问作者Rajat
相关产品推荐
相关产品推荐

