[JS] 全面解析reduce()函數(二)


Posted by mike-hsieh on 2023-10-19

本文網址: https://mike.coderbridge.io/2023/10/19/how-to-use-reduce-in-javascript-2/

延續上一章節: [JS] 全面解析reduce()函數(一)

第二篇主要以實戰方式來記錄reduce可以使用於哪些場景,以下列出30個。

1. 陣列求和:

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 15

2. 陣列求乘積:

const numbers = [1, 2, 3, 4];
const product = numbers.reduce((acc, curr) => acc * curr, 1);
console.log(product); // 24

3. 轉換成對象:

const data = [{id: 1, value: 'a'}, {id: 2, value: 'b'}];
const obj = data.reduce((acc, item) => {
    acc[item.id] = item.value;
    return acc;
}, {});
console.log(obj); // {1: 'a', 2: 'b'}

4. 統計陣列出現的屬性的數量:

const fruits = ['apple', 'banana', 'orange', 'apple', 'banana'];
const count = fruits.reduce((acc, fruit) => {
    acc[fruit] = (acc[fruit] || 0) + 1;
    return acc;
}, {});
console.log(count); // { apple: 2, banana: 2, orange: 1 }

5. 去重複:

const nums = [1, 2, 3, 2, 1, 4, 5];
const unique = nums.reduce((acc, num) => {
    if (!acc.includes(num)) {
        acc.push(num);
    }
    return acc;
}, []);
console.log(unique); // [1, 2, 3, 4, 5]

6. 攤平/扁平化陣列:

const arr2D = [[1, 2], [3, 4], [5, 6]];
const flat = arr2D.reduce((acc, curr) => acc.concat(curr), []);
console.log(flat); // [1, 2, 3, 4, 5, 6]

7. 找最大值:

const numbers = [10, 25, 65, 29, 71, 34];
const max = numbers.reduce((acc, curr) => (curr > acc ? curr : acc));
console.log(max); // 71

8. 找最小值:

const numbers = [10, 25, 65, 29, 71, 34];
const min = numbers.reduce((acc, curr) => (curr < acc ? curr : acc));
console.log(min); // 10

9. 串接字串:

const words = ['Hello', 'World', 'JavaScript', 'Rocks'];
const sentence = words.reduce((acc, word) => `${acc} ${word}`, '').trim();
console.log(sentence); // "Hello World JavaScript Rocks"

10. 組成新的陣列 (像 map):

const numbers = [1, 2, 3];
const doubled = numbers.reduce((acc, num) => {
    acc.push(num * 2);
    return acc;
}, []);
console.log(doubled); // [2, 4, 6]

11. 過濾並建立新陣列 (像 filter):

const numbers = [1, 2, 3, 4, 5];
const evens = numbers.reduce((acc, num) => {
    if (num % 2 === 0) acc.push(num);
    return acc;
}, []);
console.log(evens); // [2, 4]

12. 組合 map 和 filter:

const numbers = [1, 2, 3, 4, 5];
const doubledEvens = numbers.reduce((acc, num) => {
    if (num % 2 === 0) acc.push(num * 2);
    return acc;
}, []);
console.log(doubledEvens); // [4, 8]

13. 計算陣列中物件的某個屬性的總和:

const items = [
    { name: 'ball', price: 10 },
    { name: 'book', price: 20 },
    { name: 'pen', price: 5 }
];
const totalPrice = items.reduce((acc, item) => acc + item.price, 0);
console.log(totalPrice); // 35

14. 建立索引對應的對象:

const items = [
    { id: 'a', value: 10 },
    { id: 'b', value: 20 },
    { id: 'c', value: 5 }
];
const itemMap = items.reduce((acc, item) => {
    acc[item.id] = item.value;
    return acc;
}, {});
console.log(itemMap); // { a: 10, b: 20, c: 5 }

15. 轉置二維陣列:

const matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
];
const transpose = matrix.reduce((acc, row) => row.map((_, i) => [...(acc[i] || []), row[i]]), []);
console.log(transpose); // [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

16. 合併多個陣列:

const arrays = [[1, 2], [3, 4], [5, 6]];
const merged = arrays.reduce((acc, curr) => acc.concat(curr), []);
console.log(merged); // [1, 2, 3, 4, 5, 6]

17. 資料分組GroupBy:

const people = [
    { name: 'John', age: 25 },
    { name: 'Jane', age: 30 },
    { name: 'Tom', age: 25 }
];
const groupByAge = people.reduce((acc, person) => {
    const age = person.age;
    if (!acc[age]) {
        acc[age] = [];
    }
    acc[age].push(person);
    return acc;
}, {});
console.log(groupByAge); // { '25': [{...}, {...}], '30': [{...}] }

18. 判斷所有元素是否符合條件:

const numbers = [1, 2, 3, 4, 5];
const allAboveZero = numbers.reduce((acc, num) => acc && num > 0, true);
console.log(allAboveZero); // true

19. 轉換為新物件格式:

const data = [
    { key: 'name', value: 'John' },
    { key: 'age', value: 25 }
];
const obj = data.reduce((acc, item) => {
    acc[item.key] = item.value;
    return acc;
}, {});
console.log(obj); // { name: 'John', age: 25 }

20. 尋找陣列中的某個物件:

const users = [
    { id: 1, name: 'John' },
    { id: 2, name: 'Jane' },
    { id: 3, name: 'Tom' }
];
const user = users.reduce((acc, curr) => {
    if (curr.id === 2) {
        return curr;
    }
    return acc;
}, null);
console.log(user); // { id: 2, name: 'Jane' }

21. 計算資料的平均值:

const grades = [87, 94, 72, 60, 88];
const average = grades.reduce((acc, grade, index, array) => {
    acc += grade;
    if (index === array.length - 1) return acc / array.length;  // 表示最後一筆,就要除於總長度
    return acc;  // 表示還沒跑完
}, 0);
console.log(average); // 80.2

22. 建立鍊接對象:

const pairs = [['a', 1], ['b', 2], ['c', 3]];
const linkedObj = pairs.reduce((acc, [key, value]) => {
    acc[key] = value;
    return acc;
}, {});
console.log(linkedObj); // { a: 1, b: 2, c: 3 }

23. 轉換字串成對象:

const queryString = 'key=value&key2=value2';
const params = queryString.split('&').reduce((acc, pair) => {
    const [key, value] = pair.split('=');
    acc[key] = value;
    return acc;
}, {});
console.log(params); // { key: 'value', key2: 'value2' }

24. 求陣列的眾數(一個陣列中出現最多的數字):

const numbers = [1, 2, 3, 2, 4, 3, 5, 3];
const mode = numbers.reduce((acc, num) => {
    acc[num] = (acc[num] || 0) + 1;
    if (!acc.mode || acc[num] > acc[acc.mode]) {
        acc.mode = num;
    }
    return acc;
}, {}).mode;
console.log(mode); // 3

25. 轉換為首字母大寫的字串:

const words = ['hello', 'world'];
const capitalizedWords = words.reduce((acc, word) => {
    acc.push(word.charAt(0).toUpperCase() + word.slice(1));
    return acc;
}, []);
console.log(capitalizedWords); // ['Hello', 'World']

26.合併重複的資料項目:

const data = [
    { id: 1, value: 10 },
    { id: 2, value: 20 },
    { id: 1, value: 5 }
];
const combined = data.reduce((acc, item) => {
    const existing = acc.find(entry => entry.id === item.id);
    if (existing) {
        existing.value += item.value;
    } else {
        acc.push({ ...item });
    }
    return acc;
}, []);
console.log(combined); // [{ id: 1, value: 15 }, { id: 2, value: 20 }]

27.建立資料的階層結構(可用於建立樹狀選單):

const flat = [
    { id: 1, parent: null },
    { id: 2, parent: 1 },
    { id: 3, parent: 1 },
    { id: 4, parent: 3 }
];
const tree = flat.reduce((acc, item) => {
    if (item.parent === null) {
        acc.push(item);
    } else {
        const parent = flat.find(entry => entry.id === item.parent);
        parent.children = parent.children || [];
        parent.children.push(item);
    }
    return acc;
}, []);
console.log(tree);
//[
//  {
//    "id": 1,
//    "parent": null,
//    "children": [
//      {
//        "id": 2,
//        "parent": 1
//      },
//      {
//        "id": 3,
//        "parent": 1,
//        "children": [
//          {
//            "id": 4,
//            "parent": 3
//          }
//        ]
//      }
//    ]
//  }
//]

28.建立資料的階層結構 (更深層次):

const flat = [
    { id: 1, parent: null },
    { id: 2, parent: 1 },
    { id: 3, parent: 2 },
    { id: 4, parent: 3 }
];
const toTree = (items, parent) => items.reduce((acc, item) => {
    if (item.parent === parent) {
        const children = toTree(items, item.id);
        if (children.length) item.children = children;
        acc.push(item);
    }
    return acc;
}, []);
console.log(toTree(flat, null));
//[
//  {
//    "id": 1,
//    "parent": null,
//    "children": [
//      {
//        "id": 2,
//        "parent": 1,
//        "children": [
//          {
//            "id": 3,
//            "parent": 2,
//            "children": [
//              {
//                "id": 4,
//                "parent": 3
//              }
//            ]
//          }
//        ]
//      }
//    ]
//  }
//]

29. 連續運算:

const operations = [
    { type: 'add', value: 5 },
    { type: 'multiply', value: 3 },
    { type: 'subtract', value: 2 }
];
const result = operations.reduce((acc, op) => {
    if (op.type === 'add') return acc + op.value;
    if (op.type === 'multiply') return acc * op.value;
    if (op.type === 'subtract') return acc - op.value;
    return acc;
}, 0);
console.log(result); // 13

30. 反轉陣列:

const numbers = [1, 2, 3, 4, 5];
const reversed = numbers.reduce((acc, num) => [num, ...acc], []);
console.log(reversed); // [5, 4, 3, 2, 1]

31. 移除陣列中的偽值(0, null, false, undefined...):

const values = [0, 1, false, null, "hello", undefined, 2];
const truthyValues = values.reduce((acc, value) => {
    if (value) {
        acc.push(value);
    }
    return acc;
}, []);
console.log(truthyValues); // [1, "hello", 2]

32. 計算陣列中數值的變異數(變異數是一個統計學上的指標,用來度量數據分散的程度,或者說數據的波動大小。):

  1. const numbers = [1, 2, 3, 4, 5];
    這裡我們有一個數字陣列 numbers。
  2. const avg = numbers.reduce((acc, num) => acc + num, 0) / numbers.length;
    這裡我們使用 reduce() 函式來計算 numbers 陣列的平均值。累加器 acc 存儲目前的總和,num 是當前的數字。初始化值為 0。計算完總和後,我們再除以數字陣列的長度來獲得平均值 avg。
  3. const variance = numbers.reduce((acc, num) => acc + Math.pow(num - avg, 2), 0) / numbers.length; 這裡再次使用 reduce() 函式來計算變異數。
  • 疊代每個數字,計算該數字和平均值的差(num - avg)。
  • 使用 Math.pow 函式來計算該差的平方。
  • 將這些平方和累加起來。
  • 最後,將累加的平方和除以數字陣列的長度,得到變異數。

簡單來說,這段程式碼首先計算了數字陣列的平均值,然後計算了每個數字與平均值的差的平方的平均值,即變異數。

const numbers = [1, 2, 3, 4, 5];
const avg = numbers.reduce((acc, num) => acc + num, 0) / numbers.length;
const variance = numbers.reduce((acc, num) => acc + Math.pow(num - avg, 2), 0) / numbers.length;
console.log(variance); // 2

33. 資料的連除:

const numbers = [100, 2, 5];
const result = numbers.reduce((acc, num) => acc / num);
console.log(result); // 10

#reduce #javascript #example







Related Posts

React Elements

React Elements

JS review

JS review

[Notes] 關於企業生產上的一些小知識(1)

[Notes] 關於企業生產上的一些小知識(1)


Comments