簡體   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