# 高階函式(Higher Order function) ## 三大常用函式 : filter, map, reduce Benson 的 Github 練習檔 https://github.com/MechaChen/advanced-Javascript.git ### 1. filter (過濾函式) --- filter 函式可以幫你過濾掉陣列中不想要的部分,ex : * 商品篩選 * 條件篩選 --- 假設有一陣列 ``` jsx= const numbers = [1, -1, 2, 3]; ``` 如果今天我們想把 -1 的部分拿掉,則可以這樣寫 ``` jsx= const filtered = numbers.filter(function(value) { return value > 0; }); // filtered => [1, 2, 3] ``` (value) 為陣列中個別的值, 在 return 回傳的值中, 可以利用 value 取得的值去做判斷這個是不是你想要回傳的值 若結合ES6,可以簡化成 ``` jsx= //單行回傳不用寫 return const filtered = numbers.filter(value => value > 0); ``` 若再簡化參數 ``` jsx= const filtered = numbers.filter(n => n > 0); ``` ### 2. map (映射函式) --- map 函式可以取得一陣列的元素,接著轉換成新的陣列,ex : * 組成一 ul li 元素 * 組成一群物件 --- 繼上面的 filter 函式 ``` jsx= const numbers = [1, -1, 2, 3]; const filtered = numbers.filter(n => n > 0); // filtered => [1, 2, 3] ``` 若我們想把取得的陣列印成 ul li 標籤,可利用 map 函式 ``` jsx= const items = filtered.map(n => `<li>${n}</li>`); // 如果只印 ${items} 的話,會自動呼叫 toString() // <li>與<li>之間會出現逗點(,) // 因此用 join('') 空字串告訴它串接時不要逗點 const html = `<ul>${items.join("")}</ul>`; // html => <ul><li>1</li><li>2</li><li>3</li></ul> ``` 也可以用 map 函數製造多個物件 ``` jsx= const items = filtered.map(n => { return { value: n }; }); // items => [{ value: 1 }, { value: 2 }, { value: 3 }] ``` 因為是單行,可以省去 return 不寫 ``` jsx= const items = filtered.map(n => ({ value: n })); ``` 若把變數 n 改為 value,則因 key 的名稱與 value 的名稱相同,可縮寫為 ``` jsx= const items = filtered.map(value => ({ value })); ``` ### 3. reduce 函式 --- *array.reduce( function(accumlator, currentValue) {}, initial value of accumlator )* reduce 函式中, 第一參數為回傳函式,參數有 2 個參數,1 為累加數,1 取得陣列中每項元素, 第二個參數為累加數的初始值 --- 今有一陣列 ``` jsx= const numbers = [1, -1, 2, 3]; ``` 若今天想要取得 numbers 裡全部的總和, 以前的作法為 ``` jsx= let sum = 0; for (let i of numbers) sum += i; // sum = 5 ``` 若利用 reduce 函式 ``` jsx= a = 0, c = 1 => a = 1 // a = 1, c = -1 => a = 0 // a = 0, c = 2 => a = 2 // a = 2, c = 3 => a = 5 const sum = numbers.reduce( (accumlator, currentValue) => accumlator + currentValue, 0); // sum = 5 ``` 一樣可以得到相同的答案 若不給初始值 ``` jsx= // a = 1, c = -1 => a = 0 // a = 0, c = 2 => a = 2 // a = 2, c = 3 => a = 5 const sum = numbers.reduce( (accumlator, currentValue) => accumlator + currentValue ); // sum = 5 ``` 則會從取得陣列的第 1 數作為初始值 *參考資源* filter : https://www.youtube.com/watch?v=4_iT6EGkQfk&list=PLTjRvDozrdlxEIuOBZkMAK5uiqp8rHUax&index=17 map : https://www.youtube.com/watch?v=G3BS3sh3D8Q&list=PLTjRvDozrdlxEIuOBZkMAK5uiqp8rHUax&index=18 reduce : https://www.youtube.com/watch?v=G3BS3sh3D8Q&list=PLTjRvDozrdlxEIuOBZkMAK5uiqp8rHUax&index=19