# reduce() 是什麼?該如何使用? 昨天在面試時突然被問到有沒有使用過 reduce,一時之間腦內跑馬燈走過,有聽過這個字但好像沒有實際使用過,於是模稜兩可的給了一個很爛的回答,讓人後悔至極,應該大方承認自己沒有相關使用經驗,至少還比較有臺階可下。不過也因為如此,讓我發現自己對這個陣列的操作方法還不熟,趕緊來補強一下。 ## Array.prototype.reduce() 根據 MDN 的說明,reduce() 方法將一個累加器及陣列中每項元素(由左至右)傳入回呼函式,將陣列化為單一值。其實這個描述挺寫實的,不過我們搭配實作來看會更清楚。 ### Syntax ```javascript= array.reduce(function(accumulator, currentValue, currentIndex, array),initialValue) ``` 其中有 4 個參數,分別代表不同的意思。 * accumulator:累加總計 * currentValue:目前值 * currentIndex(optional):這一輪迭代的索引(index) * array(optional):陣列內容 而 `initialValue` 則是代表第一次要傳入的`初始值`。 ### 實例 1 ```javascript= const array = [1, 3, 4, 5] const arrayReduced = array.reduce((accumulator, currentValue) => { return accumulator + currentValue }, 5) //初始值為 5 console.log(arrayReduced) // 18 ``` | No | accumulator | currentValue | currentIndex | return value | |:---:|:-----------:|:------------:|:------------:|:------------:| | 1 | 5 | 1 | 0 | 6 | | 2 | 6 | 3 | 1 | 9 | | 3 | 9 | 4 | 2 | 13 | | 4 | 13 | 5 | 3 | 18 | 可以發現當我們的初始值是 5 的時候,`accumulator` 就是從 5 開始計算,後面接續 `currentValue` 的值累計。 ### 實例 2 reduce() 也可以用來合併陣列。 ```javascript= const array = [[1, 3, 4, 5], [6, 7, 8], [9, 10, 11]] const arrayReduced = array.reduce((accumulator, currentValue) => { return accumulator.concat(currentValue) }, []) console.log(arrayReduced) // [1, 3, 4, 5, 6, 7, 8, 9, 10, 11] ``` 或者來計算相同字串的數量並以物件呈現。 ```javascript= const array = ['apple', 'orange', 'orange', 'apple', 'apple', 'banana'] const arrayReduced = array.reduce((accumulator, currentValue) => { if (currentValue in accumulator) { accumulator[currentValue]++ } else { accumulator[currentValue] = 1 } return accumulator }, {}) console.log(arrayReduced) // {apple: 3, orange: 2, banana: 1} ``` `reduce` 的 `initialValue` 可以設為任一型態(數值、物件、陣列),而 `accumulator` 可繼承 `initialValue` 的型態並接收 `currentValue` 計算後的結果。 ## 結論 * 使用 `reduce` 可以進行比較細膩的比對與操作,尤其在陣列的 item 與 item 之間。 * 執行前記得確認 `initialValue`,因為他會決定累加器的初始值,影響 return 的結果。