[筆記] 淺淺的看一下 reduce
Array.prototype.reduce()
嗯,一直說要搞懂 reduce()
這個方法,拖了好幾天,影片看了好幾次,文件看了好幾篇,總算下定決心來好好研究一下。
The
reduce()
method executes a reducer function (that you provide) on each element of the array, resulting in single output value. MDN - Array.prototype.reduce()
這篇筆記是給至少知道 map()
、forEach()
怎麼使用的人看的,還不清楚這兩個方法的話可能會看不太懂……
為什麼它剛開始比較難搞
因為在這之前,我所學到的方法在呼叫 callback 函式的時候都「可以」只給一個參數,像是 map()
、 forEach()
,而且必要的參數就是正在處理的陣列中元素,但是這個 reduce()
所呼叫的 callback 函式,一定要有兩個基本的參數,而且第一個還不是正在處理的陣列中元素,搞的我好亂阿!
那到底 reduce()
裡的 callback 要怎麼 call 法,下面就用最基本的取陣列值總合做為例子研究一下吧!
reduce()
裡的 callback function
const numberArray = [1, 2, 3] |
在這個例子裡面,包在 .reduce()
的括號裡面的就是那個有一點點難搞的 callback 函式,它要求必要的參數有 accumulator 與 currentValue 兩個。
- accumulator 這個參數可以把它想像成一個「接收器」,它會接收每次 callback 函式回傳的值作為他的值,然後傳入 callback 函式進行下一次的處理。
- currentValue 則是「目前處理的陣列元素」。
看完兩個參數的定義肯定還是霧煞煞,它到底怎麼運作的?accumulator 的初始值會是什麼?currentValue 又會從第幾個元素開始處理?讓我們跑一遍上面這段程式的流程應該就會比較清楚了。
跟著 reduce()
跑一遍
首先,一定要先有一個陣列,不必多講。
然後看到這個 const numberSum =
的寫法應該就知道,它會回傳一個值,而這個值不會改變原始陣列,所以要請一個變數去把它接起來!
然後請出陣列,對著他使用 .reduce()
方法。
重點來了
- callback 函式開始執行,初始值的載入非常重要,其實搞懂它的初始值是什麼就懂九成了。
- accumulator 的初始值在沒有特別指定的狀況之下(等一下會講到如何指定 accumulator 的初始值),就會是陣列中的第一個元素,在這個例子中就是 index 為 0 的數字 1。
- currentValue 因為第一個元素被 accumulator 取用了,所以它會自動往下一個元素取值,在例子中就是 index 為 1 的數字 2。
現在上面這段程式就很好懂了:
- 第一次進入 callback 函式,accumulator == 1, currentValue == 2, 回傳他們的相加值 3 並傳給 accumulator 作為下一次使用。
- 第二次進入 callback 函式,accumulator == 3,currentValue == 3, 回傳他們的相加值 6,因為 currentValue 已經是陣列中的最後一個元素,所以
reduce()
方法結束,取得一個回傳值 6。 - 回傳值 6 被傳給 numberSum 變數,最後再被
console.log()
出來。如何自訂初始值
除了讓 callback 函式自動產生初始值,我們還可以自已指定初始值。
方法很簡單,就是在reduce()
方法中除了 callback 函式再傳給他另外一個參數,例如:這個「自訂的初始值」就會被傳入 accumulator 作為引數,而 currentValue 則會自動取得陣列第一個元素的值作為引數。ARRAY.reduce(function(acc, cur){}, 自訂的初始值寫在這裡)
把上面的例子改一下,加入初始值:這段程碼就在使用const numberArray = [1, 2, 3]
const numberSum = numberArray.reduce(
function(acc, cur) { return acc + cur}, 100 // 這個 100 就是「自訂的初始值」)
console.log(numberSum) // 106.reduce()
方法時把初始值設定為 100,所以第一次進入 callback 函式時 acc 的值就會是 100,而 cur 的值則會是陣列中 index 0 的值 1。接下來的執行流程應該就不必多講了。
最後的結果就是 106。
瞭解參數傳遞的邏輯之後,.reduce()
其實也不難懂,搭配其它可以傳入的參數(目前元素的 Index,陣列)還可以有其它的應用,也不那麼難理解,但是身為初學者先淺淺的學到這邊吧!其它部分未來再慢慢深入研究了。