[英]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 的答案是选择在每次迭代时检查条件,并且每次不满足条件时不断返回累加器。 这对许多用例来说都很好,但让它更明确会更好。
我知道有两种方法可以做到这一点。 一种是有一些我们会返回的信号值——可能是一个符号——说,“我们完成了,只需返回累加器。” 缺点是这个函数现在依赖于外部信号值。 这并不可怕,而且通常可能是正确的解决方案。 写起来不难,我把它留作练习。
另一种技术是要求回调明确选择是继续迭代还是通过提供next
和done
函数来停止。 如果我们想继续,我们用下一个累加器值调用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.