繁体   English   中英

对数组中的所有数字求和,直到达到某个值

[英]Sum all numbers in array until a certain value is reached

我正在编写一个函数,这是拼图的最后一块,我认为这很容易处理,但是在对 for 和 while 循环进行了一些不成功的修补后,我尝试在网上查找它,但仍然找不到回答。 我遇到了一些晦涩难懂和复杂的解决方案,但我认为应该有更直接的方法来解决这个问题。 例如,如果我有一个数组

[1, 2, 3, 5, 7, 9]

并且参数是 10,函数应该返回 6 (1 + 2 + 3),因为值的总和应该 <= 10(或传递的任何数字)。 如果参数为 4,则函数应返回 3 (1 + 2),依此类推。

您可以使用for循环:

 const arg = 10 const arr = [1, 2, 3, 5, 7, 9] let res = 0; const calc = (arr, limit) => { for (num of arr) { if (num + res > limit) { break; } res += num; } return res; } console.log(calc(arr, arg))

.reduce()每个当前值 ( cur ) 添加到累加器 ( acc ) 并检查与限制 ( max ) 的对比。 如果acc + cur小于 limit 则返回acc+ cur ,否则返回acc 根据 Spectric 的评论,如果数组发生故障,则添加.sort()

 const array = [1,2,3,5,6,8]; const mixed = [0,7,3,8,2,1]; const A = 10; const B = 15; const closest = (arr, max) => { return arr.sort((a, b) => a - b).reduce((acc, cur) => (acc + cur) > max ? acc : (acc + cur)); } console.log(closest(array, A)); console.log(closest(array, B)); console.log(closest(mixed, B));

一种有趣的方法是意识到我们想做一个折叠(类似于Array.prototype.reduce ),但我们可以提前逃脱。 zer00ne 的答案是选择在每次迭代时检查条件,并且每次不满足条件时不断返回累加器。 这对许多用例来说都很好,但让它更明确会更好。

我知道有两种方法可以做到这一点。 一种是有一些我们会返回的信号值——可能是一个符号——说,“我们完成了,只需返回累加器。” 缺点是这个函数现在依赖于外部信号值。 这并不可怕,而且通常可能是正确的解决方案。 写起来不难,我把它留作练习。

另一种技术是要求回调明确选择是继续迭代还是通过提供nextdone函数来停止。 如果我们想继续,我们用下一个累加器值调用next 如果我们完成了,我们只需调用done 这是一个版本:

 const fold = (fn) => (a) => ([x, ...xs]) => x == undefined ? a : fn (a, x, (r) => fold (fn) (r) (xs), () => a) const sumUpTo = (n) => fold ((a, x, next, done) => a + x > n ? done () : next (a + x)) (0) console .log (sumUpTo (10) ([1, 2, 3, 5, 7, 9])) //=> 6 console .log (sumUpTo (4) ([1, 2, 3, 5, 7, 9])) //=> 3 console .log (sumUpTo (10) ([1, 2, 3, 4, 5, 6])) //=> 10

sumUpTo接受我们的总值并返回一个接受数字列表的函数。 它通过使用回调函数调用fold来实现这一点,初始值(总和为0 ),并最终传递我们的数字列表。 该回调完成了我们关心的工作。 然后fold重复调用它,直到它用完值或调用done

如果它更清楚,我们可以分解上面的单行版本以专门关注回调:

const callback = (n) => (a, x, next, done) => 
  a + x > n 
    ? done () 
    : next (a + x)

const sumUpTo = (n) => fold (callback (n)) (0)

在我看来,这是一个非常优雅的模式。

代码占用最少的最快方法:

 const dataset = [1, 2, 3, 5, 7, 9] const getMaxSum = (dataset, max) => { var sum = 0, num; for( num of dataset ) { if( sum + num > max ) break // very important to break once satisfied sum += num } return sum } console.log( getMaxSum(dataset, 10) ) console.log( getMaxSum(dataset, 20) )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM