为了账号安全,请及时绑定邮箱和手机立即绑定

通过 reduce 方法对数组元素进行计数,直到出现特定值,不会给出正确的输出

通过 reduce 方法对数组元素进行计数,直到出现特定值,不会给出正确的输出

哈士奇WWW 2022-09-11 20:20:34
const arr = [5,6,0,7,8];const sum = (arr,num) => arr.reduce((total)=>(num==0 ? total : total+num), 0) console.log(sum(arr, 0))请检查我如何使它工作。做了一些错误,但不知道到底是什么。输出是函数而不是结果。
查看完整描述

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==xtruexnumtruetrue

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>

展开代码段


查看完整回答
反对 回复 2022-09-11
?
幕布斯6054654

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));


查看完整回答
反对 回复 2022-09-11
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

您需要括号来执行该函数()

sum(arr, 0)

如果不使用括号,则将对函数的引用存储在变量中


查看完整回答
反对 回复 2022-09-11
  • 3 回答
  • 0 关注
  • 145 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号