Array.reduce() - Tích lũy giá trị từ mảng
reduce() duyệt mảng từ trái sang phải, tích lũy một giá trị đơn (accumulator) qua từng phần tử. Đây là phương thức mạnh mẽ nhất của mảng - có thể thực hiện được mọi việc các phương thức khác làm được.
Cú pháp
arr.reduce(callback(accumulator, currentValue, index, array), initialValue)
Ví dụ minh họa: Tính tổng
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Reduce Array</title>
<style>
body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; }
.result, .sample { font-size: 18px; font-weight: 500; color: red; font-family: monospace; }
.result { color: blueviolet; }
button { padding: 8px 16px; cursor: pointer; }
pre { background: #f5f5f5; padding: 10px; }
</style>
</head>
<body>
<h1>Reduce Arrays trong JavaScript</h1>
<div><pre class="sample">[1, 3, 5, 6, 9, 22, 15]</pre></div>
<div class="result"></div>
<button class="btn-demo">TÍNH TỔNG</button>
<h3>Nhấn nút để tính tổng các phần tử mảng</h3>
<script>
const resEle = document.querySelector(".result");
const btn = document.querySelector(".btn-demo");
const sampleEle = document.querySelector(".sample");
const arr = [1, 3, 5, 6, 9, 22, 15];
sampleEle.textContent = arr;
btn.addEventListener("click", () => {
const sum = arr.reduce((accumulator, currentValue) => {
return accumulator + currentValue;
}, 0); // initialValue = 0
resEle.textContent = "Tổng = " + sum;
});
</script>
</body>
</html>
Cách hoạt động từng bước
arr = [1, 3, 5, 6, 9, 22, 15], initialValue = 0
Bước 1: acc=0, curr=1 → return 1
Bước 2: acc=1, curr=3 → return 4
Bước 3: acc=4, curr=5 → return 9
Bước 4: acc=9, curr=6 → return 15
Bước 5: acc=15, curr=9 → return 24
Bước 6: acc=24, curr=22 → return 46
Bước 7: acc=46, curr=15 → return 61 (kết quả cuối)
Các trường hợp sử dụng phổ biến
1. Tính tổng / tích / giá trị cực đại
const numbers = [1, 2, 3, 4, 5];
// Tổng
const sum = numbers.reduce((a, b) => a + b, 0); // 15
// Tích
const product = numbers.reduce((a, b) => a * b, 1); // 120
// Max (không cần initialValue)
const max = numbers.reduce((a, b) => a > b ? a : b); // 5
2. Đếm tần suất (Frequency count)
const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
const count = fruits.reduce((acc, fruit) => {
acc[fruit] = (acc[fruit] || 0) + 1;
return acc;
}, {});
// { apple: 3, banana: 2, orange: 1 }
3. Gom nhóm (Group by)
const people = [
{ name: 'An', age: 20 },
{ name: 'Bình', age: 25 },
{ name: 'Cường', age: 20 }
];
const byAge = people.reduce((acc, person) => {
const age = person.age;
if (!acc[age]) acc[age] = [];
acc[age].push(person);
return acc;
}, {});
// { 20: [{name:'An',age:20}, {name:'Cường',age:20}], 25: [{name:'Bình',age:25}] }
4. Làm phẳng mảng (Flatten)
const nested = [[1, 2], [3, 4], [5, 6]];
const flat = nested.reduce((acc, curr) => acc.concat(curr), []);
// [1, 2, 3, 4, 5, 6]
5. Chuyển mảng thành Object
const users = [
{ id: 1, name: 'An' },
{ id: 2, name: 'Bình' }
];
const userMap = users.reduce((acc, user) => {
acc[user.id] = user;
return acc;
}, {});
// { 1: {id:1,name:'An'}, 2: {id:2,name:'Bình'} }
6. Pipe/Compose functions
const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
const add1 = x => x + 1;
const double = x => x * 2;
const square = x => x * x;
const compute = pipe(add1, double, square);
console.log(compute(3)); // ((3+1)*2)^2 = 64
Lưu ý quan trọng
- Luôn cung cấp
initialValue(trừ khi chắc chắn mảng không rỗng và logic phù hợp). - Không có initialValue + mảng rỗng →
TypeError. reduceRight()duyệt từ phải sang trái.