Xử lý mảng trong JavaScript với map, filter và reduce

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Phần lớn dữ liệu trong ứng dụng web là danh sách: sản phẩm, bài viết, bình luận, người dùng. Biết dùng map, filter và reduce giúp bạn xử lý danh sách một cách ngắn gọn, dễ đọc, thay cho những vòng lặp for dài dòng với biến tạm.

Dữ liệu mẫu

Chúng ta dùng danh sách khóa học nhỏ cho các ví dụ:

const khoaHoc = [
  { ten: 'HTML cơ bản', gia: 200, daHoc: true },
  { ten: 'CSS nâng cao', gia: 300, daHoc: false },
  { ten: 'JavaScript', gia: 500, daHoc: true },
  { ten: 'React', gia: 700, daHoc: false },
];

map: biến đổi từng phần tử

map tạo ra mảng mới có cùng độ dài, mỗi phần tử là kết quả của hàm bạn truyền vào. Mảng gốc không thay đổi.

const tenKhoa = khoaHoc.map(k => k.ten);
// ['HTML cơ bản', 'CSS nâng cao', 'JavaScript', 'React']

const giamGia = khoaHoc.map(k => ({ ...k, gia: k.gia * 0.9 }));

Chú ý ở ví dụ hai, ta bọc đối tượng trong cặp ngoặc tròn để arrow function trả về một object literal thay vì hiểu nhầm đó là thân hàm.

filter: giữ lại phần tử thỏa điều kiện

filter trả về mảng mới chỉ gồm các phần tử mà hàm điều kiện trả về truthy:

const chuaHoc = khoaHoc.filter(k => !k.daHoc);
const reGia = khoaHoc.filter(k => k.gia <= 300);

Kết quả có thể là mảng rỗng nhưng không bao giờ là undefined, nên bạn có thể gọi tiếp các phương thức khác mà không lo lỗi.

reduce: gộp cả mảng thành một giá trị

reduce duyệt mảng và tích lũy một kết quả. Tham số thứ nhất là hàm nhận (bộ tích lũy, phần tử), tham số thứ hai là giá trị khởi đầu:

const tongTien = khoaHoc.reduce((tong, k) => tong + k.gia, 0);
// 1700

const theoTrangThai = khoaHoc.reduce((acc, k) => {
  const key = k.daHoc ? 'daHoc' : 'chuaHoc';
  acc[key] = (acc[key] || 0) + 1;
  return acc;
}, {});
// { daHoc: 2, chuaHoc: 2 }

Hãy luôn truyền giá trị khởi đầu. Nếu bỏ qua, phần tử đầu tiên sẽ làm giá trị khởi đầu, và mảng rỗng sẽ gây lỗi.

Nối chuỗi các phương thức

Sức mạnh thật sự đến khi kết hợp chúng:

const tongChuaHoc = khoaHoc
  .filter(k => !k.daHoc)
  .map(k => k.gia)
  .reduce((a, b) => a + b, 0);
// 1000

Đọc từ trên xuống: lọc các khóa chưa học, lấy giá, cộng lại. Mã gần như đọc được như một câu tiếng Việt, đây là lý do cách viết này phổ biến.

Các phương thức hữu ích khác

  • find: trả về phần tử đầu tiên thỏa điều kiện, hoặc undefined.
  • findIndex: trả về vị trí của phần tử đó, hoặc -1.
  • some: có ít nhất một phần tử thỏa điều kiện không? Trả về boolean.
  • every: mọi phần tử đều thỏa điều kiện không?
  • includes: mảng có chứa giá trị này không?
  • sort: sắp xếp, nhưng lưu ý nó thay đổi trực tiếp mảng gốc và mặc định so sánh theo chuỗi.
  • forEach: chạy một hàm cho mỗi phần tử, không trả về gì, dùng cho tác dụng phụ.
[10, 9, 1].sort();               // [1, 10, 9] (sắp theo chuỗi)
[10, 9, 1].sort((a, b) => a - b); // [1, 9, 10]

Những lỗi thường gặp

  1. Dùng map chỉ để lặp rồi bỏ kết quả. Trường hợp đó dùng forEach hoặc for...of.
  2. Quên return trong thân hàm có ngoặc nhọn, dẫn tới mảng toàn undefined.
  3. Sửa trực tiếp phần tử của mảng gốc bên trong map thay vì tạo bản sao.
  4. Lạm dụng reduce cho những việc map hoặc filter làm rõ ràng hơn.

Ví dụ: hiển thị danh sách lên trang

Trong ứng dụng thật, bạn thường biến mảng dữ liệu thành HTML. Kết hợp map với join là cách nhanh:

const html = khoaHoc
  .map(k => '<li>' + k.ten + ' - ' + k.gia + 'k</li>')
  .join('');
document.querySelector('#danh-sach').innerHTML = html;

Cẩn thận: nếu dữ liệu đến từ người dùng, chèn thẳng vào innerHTML có thể tạo lỗ hổng bảo mật XSS. Với dữ liệu không đáng tin, hãy dùng textContent hoặc tạo phần tử bằng createElement. Các framework như React xử lý việc thoát ký tự này giúp bạn, nhưng hiểu nguyên lý vẫn quan trọng.

Kết luận

Hãy nhớ: map để biến đổi, filter để lọc, reduce để gộp. Chúng không làm thay đổi mảng gốc (trừ khi bạn tự làm vậy), nối được với nhau và tạo ra mã dễ đọc.

Bạn có thể luyện thêm các bài toán xử lý dữ liệu như thế này trong các khóa học trên codebem.com nếu muốn có bài tập sát thực tế.

author_photo
Nguyễn Đình Cường

0 comment