为什么 reduce 以这种方式工作?
Why is reduce working this way?
我写了一个函数来满足以下条件:
"编写一个函数,给定一个字符串,生成所有字符索引的映射。例如,
indexes("Mississippi") 应该 return 一个映射,将 'M' 与集合 {0} 关联,'i' 与集合 {1, 4, 7, 10} 关联,并且
等等。"
但为什么在我的实现中 i
的第一个值是 1
,从而切断了 M
?
var s = 'Mississippi';
function indexes(s) {
var acc = {};
return s.split('').reduce(function(p, c, i) {
if (!acc[c]) {
acc[c] = [i];
} else {
acc[c].push(i);
}
return acc
});
}
console.log(indexes(s)); // Object {i: Array[4], s: Array[4], p: Array[2]}
因为您没有为累加器指定初始值,所以对回调的第一次调用在您的数组中有前 两个 个条目(例如,p
将是 "M"
而 c
将是 "i"
),但你没有使用 p
,所以你最终会错过 "M"
.
不提供初始值在进行直接求和时很有用(例如),但对于 这种 之类的事情,我发现最简单的方法是使用 reduce
来提供初始值,像这样:
var s = 'Mississippi';
function indexes(s) {
// Note: No `acc` here
return s.split('').reduce(function(p, c, i) {
// Note: Using `p` here
if (!p[c]) {
p[c] = [i];
} else {
p[c].push(i);
}
return p;
}, {});
// ^^-- Initializing the accumulator here
}
snippet.log(JSON.stringify(indexes(s))); // {"M":[0],"i":[1,4,7,10],"s":[2,3,5,6],"p":[8,9]}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
如果您更愿意继续使用外部 acc
,我可能会使用 forEach
而不是 reduce
。
我写了一个函数来满足以下条件:
"编写一个函数,给定一个字符串,生成所有字符索引的映射。例如, indexes("Mississippi") 应该 return 一个映射,将 'M' 与集合 {0} 关联,'i' 与集合 {1, 4, 7, 10} 关联,并且 等等。"
但为什么在我的实现中 i
的第一个值是 1
,从而切断了 M
?
var s = 'Mississippi';
function indexes(s) {
var acc = {};
return s.split('').reduce(function(p, c, i) {
if (!acc[c]) {
acc[c] = [i];
} else {
acc[c].push(i);
}
return acc
});
}
console.log(indexes(s)); // Object {i: Array[4], s: Array[4], p: Array[2]}
因为您没有为累加器指定初始值,所以对回调的第一次调用在您的数组中有前 两个 个条目(例如,p
将是 "M"
而 c
将是 "i"
),但你没有使用 p
,所以你最终会错过 "M"
.
不提供初始值在进行直接求和时很有用(例如),但对于 这种 之类的事情,我发现最简单的方法是使用 reduce
来提供初始值,像这样:
var s = 'Mississippi';
function indexes(s) {
// Note: No `acc` here
return s.split('').reduce(function(p, c, i) {
// Note: Using `p` here
if (!p[c]) {
p[c] = [i];
} else {
p[c].push(i);
}
return p;
}, {});
// ^^-- Initializing the accumulator here
}
snippet.log(JSON.stringify(indexes(s))); // {"M":[0],"i":[1,4,7,10],"s":[2,3,5,6],"p":[8,9]}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
如果您更愿意继续使用外部 acc
,我可能会使用 forEach
而不是 reduce
。