与
let str = "baaabbabbsbsssssabbaaaa";
与此
[...str].reduce((characterMap, char) => {
if (!characterMap[char]) characterMap[char] = 1;
else characterMap[char]++;
return characterMap;
}, {})
我得到{b:8,a:9,s:6}
但是当我把它简化为这个
[...str].reduce((characterMap, char) => !characterMap[char] ? characterMap[char] = 1 : characterMap[char]++, {});
它打印出1而不是{b:8,a:9,s:6}
为什么?
我首先使用减少错误吗?
答案 0 :(得分:4)
我该如何缩短?
通过:
不尝试将其刺入reduce
。 :-) reduce
在累加器值更改时适当使用。就您而言,事实并非如此。
不使用数组包装器。字符串是可迭代的,因此请直接使用该事实。
使用curiously-powerful ||
operator¹默认字符计数(如果不存在)。
只需使用循环:
const characterMap = {};
for (const char of str) {
characterMap[char] = (characterMap[char] || 0) + 1;
}
实时示例:
let str = "baaabbabbsbsssssabbaaaa";
const characterMap = {};
for (const char of str) {
characterMap[char] = (characterMap[char] || 0) + 1;
}
console.log(characterMap);
但是如果您确实要使用reduce
,则可以应用||
技巧并使用较短的名称:
const characterMap = [...str].reduce((acc, ch) => {
acc[ch] = (acc[ch] || 0) + 1;
return acc;
}, {});
实时示例:
let str = "baaabbabbsbsssssabbaaaa";
const characterMap = [...str].reduce((acc, ch) => {
acc[ch] = (acc[ch] || 0) + 1;
return acc;
}, {});
console.log(characterMap);
您可以(ab)使用逗号运算符将其强制转换为简洁的箭头功能,但会牺牲可读性和可维护性(IMHO)。
但是当我把它简化为这个
[...str].reduce((characterMap, char) => !characterMap[char] ? characterMap[char] = 1 : characterMap[char]++, {});
它打印出1而不是{b:8,a:9,s:6}
为什么?
因为您的回调函数返回!characterMap[char] ? characterMap[char] = 1 : characterMap[char]++
而不是对象的结果。因此,对它的后续调用将获得该数字,而不是对象,并且characterMap[char]
始终为false(因为1["a"]
是undefined
,等等。)
¹(在我贫乏的小博客上)
答案 1 :(得分:1)
您需要将返回的累加器作为结果。
var str = "baaabbabbsbsssssabbaaaa",
result = [...str].reduce((characterMap, char) => {
characterMap[char] = (characterMap[char] || 0) + 1; // take default value of zero
return characterMap;
}, {});
console.log(result)
但是当我把它简化为这个
[...str].reduce((characterMap, char) => !characterMap[char] ? characterMap[char] = 1 : characterMap[char]++, {});
它打印出1而不是
{ b: 8, a: 9, s: 6 }
为什么?
仅仅是因为在第一个循环中
!characterMap[char] ? characterMap[char] = 1 : characterMap[char]++
这条路线
!characterMap[char] ? characterMap[char] = 1 : characterMap[char]++
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
true characterMap['b'] = 1
返回1
,并在随后的所有迭代中,采用数字1
并尝试获取该数字的属性a
(或字符串的所有后续字母),即undefined
< / p>
!characterMap[char] ? characterMap[char] = 1 : characterMap[char]++
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
!1['a']
true 1['b'] = 1
结果为1
答案 2 :(得分:0)
如果要坚持使用箭头表达式语法,可以使用comma operator:
[...str].reduce((characterMap, chr) =>
(characterMap[chr] = (characterMap[chr] || 0) + 1, characterMap), {});
或者您可以使用Object.assign
:
[...str].reduce((characterMap, chr) =>
Object.assign(characterMap, {[chr]: (characterMap[chr] || 0) + 1}), {});