---
# System prepended metadata

title: 高階函式(Higher Order function)

---

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