reduce()统计字符出现次数中三元表达式赋值原理咨询
理解reduce中统计字符次数的三元表达式逻辑
嘿,我来帮你彻底搞懂这个三元表达式的工作原理——其实它和你习惯的if-else写法逻辑完全一致,只是用更紧凑的方式实现了而已!
先还原你的场景
假设你是用类似这样的代码来统计字符出现次数:
const chars = ['l', 'a', 's', 's', 'o']; const countResult = chars.reduce((acc, char) => { acc[char] = acc[char] ? acc[char] + 1 : 1; return acc; }, {}); console.log(countResult); // 输出 {l: 1, a: 1, s: 2, o: 1}
拆解三元表达式的执行逻辑
我们把acc[char] = acc[char] ? acc[char] + 1 : 1拆成一步步来看:
判断当前字符是否已被统计:
acc[char]是检查累加器对象(也就是acc)里有没有当前字符的统计项。- 第一次遍历字符
'l'时,acc是空对象{},所以acc['l']的值是undefined,在JS中会被判定为假值。 - 当第二次遍历到
's'时,acc['s']已经有值1(第一次遍历's'时赋值的),这时候会被判定为真值。
- 第一次遍历字符
根据判断结果赋值:三元表达式的规则是
条件 ? 条件为真时执行的代码 : 条件为假时执行的代码- 当条件为假(字符第一次出现):执行
: 1,也就是把acc[char]赋值为1,完成第一次统计。 - 当条件为真(字符已经出现过):执行
acc[char] + 1,把当前统计值加1后重新赋值给acc[char],实现次数累加。
- 当条件为假(字符第一次出现):执行
和你熟悉的if-else写法等价
把这个三元表达式转换成if-else,你就能一眼看明白:
// 等价的if-else写法 if (acc[char]) { acc[char] = acc[char] + 1; } else { acc[char] = 1; }
为什么不能直接运算赋值?
你提到的“直接运算与赋值的区别”,其实是指如果直接写acc[char] += 1,会出问题:因为第一次遍历字符时,acc[char]是undefined,undefined + 1会得到NaN,最终统计结果就全是NaN了。而三元表达式(或if-else)先做了存在性判断,避免了这个问题。
用console.log看每一步的变化
你可以在reduce里加入日志,直观看到每一步的赋值过程:
const chars = ['l', 'a', 's', 's', 'o']; const countResult = chars.reduce((acc, char) => { console.log(`当前字符:${char},当前累加器:`, {...acc}); acc[char] = acc[char] ? acc[char] + 1 : 1; return acc; }, {}); console.log('最终统计结果:', countResult);
输出的日志会是:
当前字符:l,当前累加器: {}
当前字符:a,当前累加器: { l: 1 }
当前字符:s,当前累加器: { l: 1, a: 1 }
当前字符:s,当前累加器: { l: 1, a: 1, s: 1 }
当前字符:o,当前累加器: { l: 1, a: 1, s: 2 }
最终统计结果: { l: 1, a: 1, s: 2, o: 1 }
这样就能清晰看到每一次三元表达式是如何完成赋值的啦!
内容的提问来源于stack exchange,提问作者bakrall
相关产品推荐
相关产品推荐

