[英]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.