jas0nhuang

[筆記] 淺淺的看一下 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]
const numberSum = numberArray.reduce(
function(accumulator, currentValue) { // 特地把它弄出來
return accumulator + currentValue // !!!!!!!!!!!!!!!!!!!!!!!!
} // 平常不要這樣寫
)
console.log(numberSum) // 6

在這個例子裡面,包在 .reduce() 的括號裡面的就是那個有一點點難搞的 callback 函式,它要求必要的參數有 accumulator 與 currentValue 兩個。

  1. accumulator 這個參數可以把它想像成一個「接收器」,它會接收每次 callback 函式回傳的值作為他的值,然後傳入 callback 函式進行下一次的處理。
  2. currentValue 則是「目前處理的陣列元素」。

看完兩個參數的定義肯定還是霧煞煞,它到底怎麼運作的?accumulator 的初始值會是什麼?currentValue 又會從第幾個元素開始處理?讓我們跑一遍上面這段程式的流程應該就會比較清楚了。

跟著 reduce() 跑一遍

首先,一定要先有一個陣列,不必多講。
然後看到這個 const numberSum = 的寫法應該就知道,它會回傳一個值,而這個值不會改變原始陣列,所以要請一個變數去把它接起來!
然後請出陣列,對著他使用 .reduce() 方法。

重點來了

  • callback 函式開始執行,初始值的載入非常重要,其實搞懂它的初始值是什麼就懂九成了。
  • accumulator 的初始值在沒有特別指定的狀況之下(等一下會講到如何指定 accumulator 的初始值),就會是陣列中的第一個元素,在這個例子中就是 index 為 0 的數字 1。
  • currentValue 因為第一個元素被 accumulator 取用了,所以它會自動往下一個元素取值,在例子中就是 index 為 1 的數字 2。

現在上面這段程式就很好懂了:

  1. 第一次進入 callback 函式,accumulator == 1, currentValue == 2, 回傳他們的相加值 3 並傳給 accumulator 作為下一次使用。
  2. 第二次進入 callback 函式,accumulator == 3,currentValue == 3, 回傳他們的相加值 6,因為 currentValue 已經是陣列中的最後一個元素,所以 reduce() 方法結束,取得一個回傳值 6。
  3. 回傳值 6 被傳給 numberSum 變數,最後再被 console.log() 出來。

    如何自訂初始值

    除了讓 callback 函式自動產生初始值,我們還可以自已指定初始值。
    方法很簡單,就是在 reduce() 方法中除了 callback 函式再傳給他另外一個參數,例如:
    ARRAY.reduce(function(acc, cur){}, 自訂的初始值寫在這裡)
    這個「自訂的初始值」就會被傳入 accumulator 作為引數,而 currentValue 則會自動取得陣列第一個元素的值作為引數。
    把上面的例子改一下,加入初始值:
    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,陣列)還可以有其它的應用,也不那麼難理解,但是身為初學者先淺淺的學到這邊吧!其它部分未來再慢慢深入研究了。