Skip to main content

JavaScript 中的 map、filter 和 reduce:比較與教學

1. map():轉換每個元素

概念解釋:map() 就像是給陣列的每個元素「換裝」,它會依序對每個元素執行你提供的函數,然後把結果組成一個新陣列回傳。適合用在「轉換資料」的情境,例如把數字變成字串,或計算每個項目的新值。

優點:簡單、直覺,程式碼短小。 缺點:如果陣列很大,可能會產生多餘的中間陣列(但在現代瀏覽器中,效能通常沒問題)。

步驟教學

  • 步驟 1:建立一個陣列,例如 const numbers = [1, 2, 3, 4, 5];。

  • 步驟 2:呼叫 map() 方法,裡面傳入一個箭頭函數(或傳統函數),函數接收每個元素(這裡叫 num),對它做轉換(例如乘以 2)。

  • 步驟 3:把結果存到變數中,然後用 console.log() 印出來看。

  • 步驟 4:在 Console 中執行,觀察結果是 [2, 4, 6, 8, 10]。

完整程式碼範例

// 步驟 1: 建立陣列
const numbers = [1, 2, 3, 4, 5];

// 步驟 2 & 3: 使用 map 將每個數字乘以 2
const doubledNumbers = numbers.map(function(num) {
// 這裡是箭頭函數的傳統寫法,你也可以用箭頭函數簡寫:num => num * 2
return num * 2;
});

// 步驟 4: 印出結果
console.log('Map 結果:', doubledNumbers); // 輸出:Map 結果: [2, 4, 6, 8, 10]

實際應用情境:在 React 元件中,你可能用 map() 來渲染一個清單,例如把使用者資料轉成 JSX 元件。

2. filter():篩選元素

概念解釋:filter() 像是一道「過濾網」,它會檢查陣列的每個元素,符合條件的才留下,組成一個新陣列回傳。適合用在「挑選資料」的情境,例如找出偶數或特定條件的項目。

優點:邏輯清楚,容易讀懂篩選條件。 缺點:如果篩選條件複雜,函數內的邏輯可能變長。

步驟教學

  • 步驟 1:同樣用 const numbers = [1, 2, 3, 4, 5];。

  • 步驟 2:呼叫 filter(),傳入一個函數,函數返回 true(留下)或 false(丟掉)。例如,檢查 num % 2 === 0(是否為偶數)。

  • 步驟 3:存結果並印出。

  • 步驟 4:執行後,結果是 [2, 4](只留下偶數)。

完整程式碼範例

// 步驟 1: 建立陣列
const numbers = [1, 2, 3, 4, 5];

// 步驟 2 & 3: 使用 filter 篩選偶數
const evenNumbers = numbers.filter(function(num) {
// 這裡檢查 num 是否能被 2 整除,返回 true/false
return num % 2 === 0;
// 你也可以用箭頭函數簡寫:num => num % 2 === 0
});

// 步驟 4: 印出結果
console.log('Filter 結果:', evenNumbers); // 輸出:Filter 結果: [2, 4]

實際應用情境:在前端搜尋功能中,用 filter() 過濾出符合關鍵字的資料。

3. reduce():累積計算

概念解釋:reduce() 是「歸約」操作,它從陣列的第一個元素開始,逐步「累積」計算(用一個初始值),最後回傳一個單一值(不是陣列)。適合用在「彙總資料」的情境,例如求和、找最大值,或建構物件。

優點:功能強大,能處理複雜的累積邏輯。 缺點:初學者可能覺得抽象,需要多練習初始值和累加器的概念。

步驟教學

  • 步驟 1:建立陣列 const numbers = [1, 2, 3, 4, 5];。

  • 步驟 2:呼叫 reduce(),傳入一個函數(兩個參數:acc 是累加器,num 是當前元素),和初始值(例如 0,用來求和)。

  • 步驟 3:函數內更新 acc(例如 acc + num),最後 return acc。

  • 步驟 4:執行後,結果是 15(1+2+3+4+5)。

完整程式碼範例

// 步驟 1: 建立陣列
const numbers = [1, 2, 3, 4, 5];

// 步驟 2 & 3: 使用 reduce 計算總和
const sum = numbers.reduce(function(acc, num) {
// acc 是累加器,從初始值 0 開始
// 第一次:acc=0, num=1 → acc=1
// 第二次:acc=1, num=2 → acc=3
// ... 以此類推
return acc + num;
}, 0); // 第二個參數是初始值,預設是陣列第一個元素,但建議明確指定

// 步驟 4: 印出結果
console.log('Reduce 結果:', sum); // 輸出:Reduce 結果: 15

實際應用情境:計算購物車總金額,或在資料視覺化中彙總統計。

map vs. filter vs. reduce:快速比較表格

為了讓你更容易記住,我用表格整理它們的差異。記住,選擇哪個方法取決於你的需求:轉換用 map、篩選用 filter、累積用 reduce。

特性map()filter()reduce()
主要用途轉換每個元素(1:1 對應)篩選符合條件的元素(1:多)累積計算成單一值(多:1)
回傳類型新陣列(長度相同)新陣列(長度可能變短)單一值(數字、物件等)
函數參數單一元素(e.g., num)單一元素,返回 true/false累加器 (acc) + 元素 (num) + 初始值
範例結果[1,2,3] → [2,4,6][1,2,3] → [2] (偶數)[1,2,3] → 6 (總和)
效能考量適合簡單轉換適合資料過濾適合彙總,避免多餘陣列
常見錯誤忘記 return條件邏輯錯初始值沒設,導致 undefined