# 高階函式(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