Explore all courses in this category.
Explore all courses in this category.
Nguyễn Đình Cường
0 comment
09 Nov, 2026
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.
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 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 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 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.
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.
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]map chỉ để lặp rồi bỏ kết quả. Trường hợp đó dùng forEach hoặc for...of.undefined.map thay vì tạo bản sao.reduce cho những việc map hoặc filter làm rõ ràng hơn.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.
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ế.
Nguyễn Đình Cường
0 comment