iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 11
0
Modern Web

前端開發 30 個問題系列 第 11

JavaScript reduce function

  • 分享至 

  • xImage
  •  

前言
2020 秋天,我將用 30 天的時間,來嘗試回答和網路前端開發相關的 30 個問題。30 天無法一網打盡浩瀚的前端知識,有些問題可能對有些讀者來說相對簡單,不過期待這趟旅程,能幫助自己、也幫助讀者打開不同的知識大門。有興趣的話,跟著我一起探索吧!

Reduce

昨天忘記提到,最近幾天進入 JavaScript 的世界,會開始介紹一些我覺得有趣或重要的問題或內容 :)

Map, Filter, Reduce 是 JavaScript array 當中三種常用的方法。Map 的目的是遍歷所有 item,經過處理之後,回傳同樣長度的陣列;filter 同樣是遍歷所有 item,但是回傳符合條件的 items。

不過 Reduce 的功能就更為強大了,不僅僅有累加的功能,更可以實現 map 和 filter 的功能,可以說應用場景非常的廣。

所以,今天就來特別介紹一下 reduce 方法。

Syntax

reduce 的基本結構如下:

array.reduce((acc, cur, index, array) => {
  // do something
  return acc
}, initialValue)

除了一般 array method 當中 callback function 會接收的

  • cur (current value)
  • index
  • array ( array 自己本身)

之外,還多了一個 acc (accumulator),中文是累加器的意思。這個累加器會接收上一次迭代後的回傳值,所以通常 callback function 裡面會 return acc,作為下一次迭代的 arr 值。

這個 acc 可以是 number, string, array 甚至是 object,因此操作的彈性非常大!

等等,那第一次迭代當中, acc 會是什麼?

第一次迭代當中,沒有機會接收到上一次迭代的回傳值,因此這時候的 acc 會有兩種情況:

1. 有設定 initialValue

在有設定 initialValue 的情況下,acc 就會是這個 initialValue,同時,reduce() 就會從 array[0] 開始迭代。

let array = [0, 1, 2, 3, 4]
array.reduce((acc, cur, index, array) => {
   acc += cur
   return acc
}, 99)

在第一次迭代當中,acc, cur, index 分別為 99, 0, 0,在 callback function 當中執行 acc + cur 並回傳 acc,因此,在第二次的迭代當中 acc, cur, index 分別為 99, 1, 1,以此類推

2. 沒有設定 initialValue

如果沒有設定 initialValue 的話,acc 預設為 array 的第一個值,同時,reduce 就會從 array[1] 開始迭代。以下面這個例子來說

let array = [0, 1, 2, 3, 4]
array.reduce((acc, cur, index, array) => {
   acc += cur
   return acc
})

在第一次迭代當中,acc, cur, index 分別為 0, 1, 1,然後回傳結果 1 ;在第二次的迭代當中 acc, cur, index 則為 1, 2, 2,以此類推。

基本累加功能

一開始設定累加器 acc 為 0,接著,在每一次的迭代當中,把 cur (curren value) 加入到 acc 當中:

let array = [0, 1, 2, 3, 4]
array.reduce((acc, cur) => {
   acc += cur
   return acc
}, 0)

實現 map 功能

map() 可以幫助我們轉化 array 當中的所有 elements,譬如全部乘以 2 並回傳結果陣列

let array = [0, 1, 2, 3, 4]
array.map(item => item * 2)     // [ 0, 2, 4, 6, 8 ]

這裡我們也可以用 reduce() 來做到!只要設定 acc 初始值為一個 empty array,在每一次的迭代放入 cur 乘以 2 的結果

let array = [0, 1, 2, 3, 4]
array.reduce((acc, cur) => {
   acc.push(cur * 2)
   return acc
}, [])

最後可以得到一個同樣的結果

實現 filter 功能

如果要篩選出 array 當中的偶數,只要在 callback function 當中透過 if/else 來篩選出我們要的 element,然後再放入 acc 這個 array 當中,就可以得到我們想要的結果囉

let array = [0, 1, 2, 3, 4]
array.reduce((acc, cur) => {
   if (cur % 2 === 0) {
     acc.push(cur)
   }
   return acc
}, [])

實現 join 功能

其實用 join() 就很方便了,不過這裡只是想示範 reduce() 可以做很多種事情。如果我們想要達到 array.join('-') 的效果,可以這麼做:

let array = ['this', 'is', 'a', 'book']
array.reduce((acc, cur, index) => {
  if (index === 0) return acc = cur
  acc += '-' + cur
  return acc
},'')

會得到結果 "this-is-a-book"

其他應用

如果我們要同時計算 array 當中所有數值的總和與平均,這裡我們可以使用 reduce() 一口氣完成:

let array = [0, 1, 2, 3, 4]
let result = array.reduce((acc, cur, index) => {
  acc.sum += cur
  acc.avg = (acc.avg * (index) + cur)/(index + 1)
  return acc
}, {sum: 0, avg: 0})

這裡我設定 arr 的初始值為一個 object,當中分別紀錄總和與平均的值。最後可以得到結果 { sum: 10, avg: 2 }

End

Reduce 不僅僅只是一個 JavaScript 當中的 function,之後在不同的地方也會看到類似的身影出現,譬如 Redux 當中的 reducer,其實就是類似的模式。看完之後希望大家能夠更靈活運用這個好方法,我們明天繼續在 JavaScript 的世界中打滾吧!

Ref


TD
Be curious as astronomer, think as physicist, hack as engineer, fight as baseball player
More about me

"Life is like riding a bicycle. To keep your balance, you must keep moving."


上一篇
"This" in JavaScript
下一篇
JavaScript Iterator & Generator
系列文
前端開發 30 個問題31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
ph822720355
iT邦新手 5 級 ‧ 2024-01-12 09:14:09

這兩邊文章不錯,蠻詳細的!
理論篇: [JS] 全面解析reduce()函數(一)
實戰篇: [JS] 全面解析reduce()函數(二) (裡面有32個範例,一定有客官要的需求~)

我要留言

立即登入留言