本文網址: 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. 計算陣列中數值的變異數(變異數是一個統計學上的指標,用來度量數據分散的程度,或者說數據的波動大小。):
- const numbers = [1, 2, 3, 4, 5];
這裡我們有一個數字陣列 numbers。 - const avg = numbers.reduce((acc, num) => acc + num, 0) / numbers.length;
這裡我們使用 reduce() 函式來計算 numbers 陣列的平均值。累加器 acc 存儲目前的總和,num 是當前的數字。初始化值為 0。計算完總和後,我們再除以數字陣列的長度來獲得平均值 avg。 - 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