3 回答

TA贡献1828条经验 获得超4个赞
这样做很尴尬,因为它会遍历整个阵列。如果我们做一个幼稚的实现,你可以看到问题:.reduce
const arr = [5,6,0,7,8];
const sum = (arr,num) => arr.reduce((total, x)=>(num==x ? total : total+x), 0)
console.log(sum(arr, 0))
我们现在正确进行检查 - 将在为零时返回(的值)。但是,结果是错误的,因为这只返回一次,但任何其他迭代它仍然是 。以下是描述该过程每个步骤的更多日志记录的相同内容:num==x
true
x
num
true
true
const arr = [5,6,0,7,8];
const sum = (arr,num) => arr.reduce((total, x)=> {
const boolCheck = num==x;
const result = boolCheck ? total : total+x;
console.log(
`total: ${total}
num: ${num}
x: ${x}
boolCheck: ${boolCheck}
result: ${result}`);
return result;
}, 0)
console.log(sum(arr, 0))
展开代码段
因此,您需要添加一些在迭代之间持续存在的标志,这样它就不会丢失。
一种选择是在回调中更改外部标志:reduce
const arr = [5,6,0,7,8];
const sum = (arr,num) => {
let finished = false;
return arr.reduce((total, x) => {
if(x === num)
finished = true;
return finished ? total : total+x;
}, 0)
}
console.log(sum(arr, 0))
展开代码段
或者,您可以将该标志放在回调内部,并在调用之间传递它。它最终以相同的方式工作,但使回调函数纯净。以一些非正统结构为代价:reduce
const arr = [5,6,0,7,8];
const sum = (arr,num) => {
return arr.reduce(({total, finished}, x) => {
if(x === num)
finished = true;
total = finished ? total : total+x;
return {total, finished};
}, {total: 0, finished: false})
.total
}
console.log(sum(arr, 0))
展开代码段
如果要使用但可以使用其他方法,则可以使用 Array#indexOf 来查找值的第一个实例,并使用 Array#切片包含任何值的数组,直到目标值:reduce
const arr = [5,6,0,7,8];
const sum = (arr,num) => {
const endIndex = arr.indexOf(num);
return arr.slice(0, endIndex)
.reduce((total, x)=> total+x, 0)
}
console.log(sum(arr, 0))
展开代码段
或作为一个链式表达式:
const arr = [5,6,0,7,8];
const sum = (arr,num) => arr
.slice(0, arr.indexOf(num))
.reduce((total, x)=> total+x, 0);
console.log(sum(arr, 0))
展开代码段
其他库可能有一个更接近你想要的或操作 - 它从一开始就给你一个数组到给定的值或条件。然后,您可以减少结果。takeUntiltakeWhile
下面是一个使用洛达什#takeWhile的示例
通过在此处使用链接,Lodash 将执行惰性求值,因此它只会遍历数组一次,而不是扫描一次以找到最终索引并再次遍历数组以求和它。
const arr = [5,6,0,7,8];
const sum = (arr,num) => _(arr)
.takeWhile(x => x !== num)
.reduce((total, x)=>total+x, 0)
console.log(sum(arr, 0))
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
展开代码段
请注意,如果您使用的是洛达什语,那么您也可以使用 _.sum()。我上面不是为了说明通用/的外观。takeUntiltakeWhile
const arr = [5, 6, 0, 7, 8];
const sum = (arr, num) => _(arr)
.takeWhile(x => x !== num)
.sum()
console.log(sum(arr, 0))
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
展开代码段

TA贡献1876条经验 获得超7个赞
由于您需要停止在数组中对值求和,因此这可能最简单地使用循环来实现:for
const arr = [5, 6, 0, 7, 8];
const num = 0;
let sum = 0;
for (let i = 0; i < arr.length; i++) {
if (arr[i] == num) break;
sum += arr[i];
}
console.log(sum);
展开代码段
如果要使用 ,则需要保留一个标志,说明是否已看到该值,以便停止从数组中添加值:reducenum
const arr = [5, 6, 0, 7, 8];
const sum = (arr, num) => {
let seen = false;
return arr.reduce((c, v) => {
if (seen || v == num) {
seen = true;
return c;
}
return c + v;
}, 0);
}
console.log(sum(arr, 0));
console.log(sum(arr, 8));
添加回答
举报