---
# System prepended metadata

title: reduce
tags: [reduce]

---

---
title: reduce
tags: reduce,
description:
---
reduce
===

:::success
**reduce()** 將一個**累加器(accumulator)** 及**陣列中每項元素
(currentValue)** 傳入**回呼函式(callback function)**，將陣列化為單一值。
:::

```javascript=
arr.reduce(function(accumulator, currentValue, currentIndex, array), initialValue)
```
- **accumulator**： 累積回傳值的累加器，會傳入**前一次**的累加值。
- **currentValue**：當前陣列元素item。
- **currentIndex**：當前陣列索引index。
- **array**：當前陣列。
- **initialValue**：累加器初始值。不代入初始值會以陣列第一個item代入。

**currentIndex**、**array**、**initialValue**視狀況選擇性代入。
<br>

### reduce的用法

- **陣列數字累加** 
  
  把陣列內的數字累加並回傳，累加器初始值不代入，從100開始累加，最後將1500賦予給變數sum。
```javascript=
const num = [100, 200, 300, 400, 500];
let sum =  num.reduce((acc, cur) => acc += cur);
console.log(sum);
```
<br>

- **字串Unicode值累加**

  `a = 1`、`b = 2`......`z = 26`，將字串文字 **(限小寫)** 依此順序轉換數字後累加。

  - `[...str]`先將字串拆成陣列。
  
  - 累加器代入初始值0，當前item`.charCodeAt(0)`取第一個字元轉換成`Unicode`，減96的原因是a的`Unicode`是97。
  
  - 第一次`0 + cur.charCodeAt(0) - 96`，第二次`前一次累加 + cur.charCodeAt(0) - 96`，全部執行完後`return`回傳。

```javascript=
function wordsToMarks(str) {
  return [...str].reduce((acc, cur) => acc + cur.charCodeAt(0) - 96, 0);
};
console.log(wordsToMarks('abcd'));    // 10
```
<br>

- **帳戶資訊計算**

    小明有固定存錢的好習慣，以下是小明的銀行帳戶資訊。
    1. 請協助他將存款資訊 mingTransfer 的內容合併到 mingAccount.depositRecord 陣列中（使用 `.push()`）。
    2. 請將他各月的存款累加到 mingAccount.deposit 中（可以使用 `forEach()` 或 `reduce()`）

       參考: https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

```javascript=
// 小明的銀行帳戶資訊
let mingAccount = {
  name: '小明',
  age: 22,
  deposit: 10000,
  depositRecord: [
    {
      title: '開戶',
      amounts: 10000
    }
  ]
};
// 小明的存款資訊
let mingTransfer = [
  {
    title: '一月存款',
    amounts: 777
  },
  {
    title: '二月存款',
    amounts: 7000
  },
  {
    title: '三月存款',
    amounts: 70000
  }
]
console.log(mingAccount);
```
解法：

```javascript=
// 小明的銀行帳戶資訊
    let mingAccount = {
      name: '小明',
      age: 22,
      deposit: 10000,
      depositRecord: [
        {
          title: '開戶',
          amounts: 10000
        }
      ]
    };
    // 小明的存款資訊
    let mingTransfer = [
      {
        title: '一月存款',
        amounts: 777
      },
      {
        title: '二月存款',
        amounts: 7000
      },
      {
        title: '三月存款',
        amounts: 70000
      }
    ];
      // 存款資訊push到mingAccount.depositRecord
    for (const item of mingTransfer) {
      mingAccount.depositRecord.push(item);
    };
    // mingTransfer使用reduce計算加總，初值代入mingAccount.deposit
    mingAccount.deposit = mingTransfer.reduce((acc, item) => acc + item.amounts, mingAccount.deposit);
    console.log(mingAccount);
```