Hướng Dẫn Toàn Diện Về map(), filter() Và reduce() Trong JavaScript

  • Home
  • Hướng Dẫn Toàn Diện Về map(), filter() Và reduce() Trong JavaScript

Trong lập trình JavaScript hiện đại (ES6+), Functional Programming (lập trình hướng hàm) đã trở thành một tiêu chuẩn không thể thiếu. Trung tâm của phương pháp này là 3 phương thức xử lý mảng (Array Methods) vô cùng mạnh mẽ: map(), filter(), và reduce().

Thay vì sử dụng các vòng lặp truyền thống như for hay while, bộ ba này giúp code của bạn trở nên ngắn gọn, dễ đọc, dễ bảo trì và hạn chế phát sinh lỗi (side effects).

1. Phương Thức map() – Biến Đổi Dữ Liệu

map() dùng để làm gì?

map() duyệt qua từng phần tử của mảng ban đầu, áp dụng một hàm biến đổi lên phần tử đó và trả về một mảng MỚI chứa các giá trị đã được thay đổi. Mảng gốc ban đầu sẽ không bị thay đổi (immutability).

Cú pháp

const newArray = array.map((currentValue, index, array) => {
  // Trả về giá trị mới cho mảng newArray
});

Ví dụ thực tế

Bài toán: Tính giá sau thuế (VAT 10%) cho danh sách sản phẩm.

const products = [
  { name: 'Laptop', price: 1000 },
  { name: 'Phone', price: 500 },
  { name: 'Tablet', price: 300 }
];

const productsWithVAT = products.map(product => {
  return {
    ...product,
    priceWithVAT: product.price * 1.1
  };
});

console.log(productsWithVAT);
/*
[
  { name: 'Laptop', price: 1000, priceWithVAT: 1100 },
  { name: 'Phone', price: 500, priceWithVAT: 550 },
  { name: 'Tablet', price: 300, priceWithVAT: 330 }
]
*/

2. Phương Thức filter() – Lọc Dữ Liệu Theo Điều Kiện

filter() dùng để làm gì?

Đúng như tên gọi, filter() được dùng để lọc ra các phần tử thỏa mãn một điều kiện nhất định. Phương thức này chạy qua từng phần tử và kiểm tra giá trị trả về của hàm callback (true hoặc false):

  • Nếu true: phần tử đó được giữ lại.

  • Nếu false: phần tử đó bị loại bỏ.

Kết quả trả về là một mảng MỚI chỉ chứa các phần tử đạt yêu cầu.

Cú pháp

const filteredArray = array.filter((currentValue, index, array) => {
  // Trả về true để giữ lại phần tử, false để loại bỏ
});

Ví dụ thực tế

Bài toán: Lọc danh sách các đơn hàng đã hoàn thành (status: 'completed').

const orders = [
  { id: 101, status: 'completed', total: 250 },
  { id: 102, status: 'pending', total: 120 },
  { id: 103, status: 'completed', total: 450 },
  { id: 104, status: 'cancelled', total: 90 }
];

const completedOrders = orders.filter(order => order.status === 'completed');

console.log(completedOrders);
/*
[
  { id: 101, status: 'completed', total: 250 },
  { id: 103, status: 'completed', total: 450 }
]
*/

3. Phương Thức reduce() – Gom Tụ Dữ Liệu Về Một Giá Trị Single

reduce() dùng để làm gì?

reduce() là phương thức mạnh mẽ và linh hoạt nhất trong cả ba. Nó được sử dụng để duyêt qua toàn bộ mảng và “gom tụ” (accumulate) tất cả phần tử về một giá trị duy nhất (có thể là một số, một chuỗi, một object, hoặc thậm chí là một mảng mới).

Cú pháp

const result = array.reduce((accumulator, currentValue, index, array) => {
  // Trả về giá trị mới cho accumulator trong bước tiếp theo
}, initialValue);
  • accumulator (biến tích lũy): Lưu trữ kết quả tích lũy sau mỗi lần lặp.

  • initialValue (giá trị khởi tạo): Giá trị ban đầu của accumulator. Lưu ý: Luôn nên truyền initialValue để tránh các lỗi không mong muốn.

Ví dụ thực tế

Bài toán 1: Tính tổng doanh thu từ danh sách đơn hàng.

const cart = [
  { item: 'Bàn phím', price: 50, quantity: 2 },
  { item: 'Chuột', price: 25, quantity: 1 },
  { item: 'Màn hình', price: 200, quantity: 1 }
];

const totalBill = cart.reduce((total, item) => {
  return total + (item.price * item.quantity);
}, 0);

console.log(totalBill); // Output: 325 (50*2 + 25*1 + 200*1)

Bài toán 2: Phân loại và đếm số lượng thành viên theo vai trò (Role).

const users = [
  { name: 'An', role: 'admin' },
  { name: 'Bình', role: 'user' },
  { name: 'Cường', role: 'user' },
  { name: 'Dũng', role: 'editor' }
];

const roleCount = users.reduce((acc, user) => {
  acc[user.role] = (acc[user.role] || 0) + 1;
  return acc;
}, {});

console.log(roleCount);
// Output: { admin: 1, user: 2, editor: 1 }

4. Bảng So Sánh Nhanh map(), filter(), reduce()

Tiêu chí map() filter() reduce()
Mục đích chính Biến đổi từng phần tử trong mảng Lọc các phần tử theo điều kiện Tích lũy mảng thành 1 giá trị duy nhất
Kết quả trả về Mảng mới cùng độ dài với mảng gốc Mảng mới có độ dài $\le$ mảng gốc Một giá trị tùy ý (number, object, array…)
Thay đổi mảng gốc? Không Không Không

5. Kết Hợp Cả Ba Phương Thức (Method Chaining)

Sức mạnh thực sự của Functional Programming xuất hiện khi bạn kết hợp cả 3 phương thức này lại với nhau thông qua kỹ thuật Chaining (chuỗi phương thức).

Bài toán: Bạn có danh sách đơn hàng. Hãy tính tổng doanh thu từ các đơn hàng đã hoàn thành (completed) sau khi chiết khấu 10% cho các đơn đó.

const transactions = [
  { id: 1, amount: 100, status: 'completed' },
  { id: 2, amount: 200, status: 'pending' },
  { id: 3, amount: 300, status: 'completed' },
  { id: 4, amount: 50, status: 'completed' }
];

const totalRevenue = transactions
  // 1. Lọc ra các đơn hàng đã completed
  .filter(item => item.status === 'completed')
  // 2. Tính giá sau chiết khấu 10% cho từng đơn
  .map(item => item.amount * 0.9)
  // 3. Cộng tổng tất cả số tiền
  .reduce((sum, amount) => sum + amount, 0);

console.log(totalRevenue); 
// Giải thích: (100*0.9) + (300*0.9) + (50*0.9) = 90 + 270 + 45 = 405

Tổng Kết

  • Dùng map() khi bạn muốn biến đổi từng phần tử của mảng.

  • Dùng filter() khi bạn muốn chọn lọc một tập con từ mảng ban đầu.

  • Dùng reduce() khi bạn muốn tổng hợp mảng thành một kết quả đơn lẻ.

Nắm vững bộ ba map(), filter(), và reduce() sẽ giúp mã nguồn JavaScript của bạn chuẩn mực, sạch sẽ và tối ưu hơn rất nhiều. Chúc các bạn học tập tốt tại DC SoftTech!

Categories:

Leave Comment