F8

FULLSTACK HUB

👤
JavaScript🕒 30 tháng 6, 2026 lúc 15:28

Bộ ba nguyên tử: Map, Filter, Reduce

Để hiểu tường tận và nhớ suốt đời bộ ba này, bạn phải dẹp ngay mấy cái định nghĩa học thuật khô khan đi. Hãy tưởng tượng bạn đang là một đầu bếp đứng trong căn bếp của mình, đối mặt với một rổ nguyên liệu mảng gốc: const roNguyenLieu = ['🥩', '🍗', '🥔', '🥕'];

Dưới đây là tấm bản đồ trực quan bằng hình ảnh và tư duy giúp bạn neo kiến thức này vào não vĩnh viễn.

1. map() — Nhà máy chế biến (Thay quần áo mới)

  • Bản chất tối thượng: Đầu vào có 4 phần tử, đầu ra bắt buộc phải có 4 phần tử. map() không bao giờ làm mất phần tử nào, nó chỉ biến đổi hình dạng của từng phần tử theo một công thức chung.

  • Hình ảnh nhớ lâu: Bạn mang rổ nguyên liệu đi NƯỚNG.

    • 🥩 biến thành 🥩 nướng

    • 🍗 biến thành 🍗 nướng

    • Kết quả trả về: Một rổ đồ ăn chín gồm 4 món.

    Cú pháp và cái bẫy return

    Rất nhiều bạn mới học viết map như thế này và kết quả ra một mảng toàn undefined:

    // CODE SAI (Thiếu return)
    const doNuong = roNguyenLieu.map(item => {
        item + '🔥'; 
    }); // Kết quả: [undefined, undefined, undefined, undefined]
    Mẹo nhớ lâu: Đã mở ngoặc nhọn {} trong hàm thì BẮT BUỘC phải có từ khóa return. Nếu muốn viết tắt không cần return, hãy bỏ luôn dấu ngoặc nhọn!
    // CODE ĐÚNG (Viết ngắn gọn - Implicit Return)
    const doNuongGọn = roNguyenLieu.map(item => item + '🔥');
    // Kết quả: ['🥩🔥', '🍗🔥', '🥔🔥', '🥕🔥']

    2. filter() — Người gác cổng (Lọc đồ đạt chuẩn)

    • Bản chất tối thượng: Chạy qua từng phần tử, chấm điểm Đúng (true) hoặc Sai (false). Thằng nào được chấm true thì được copy sang mảng mới, thằng nào false bị vứt lại. Số lượng mảng mới luôn nhỏ hơn hoặc bằng mảng cũ.
    • Hình ảnh nhớ lâu: Bạn là người ăn chay, bạn chỉ muốn lọc lấy RAU CỦ.
    +) 🥩 -> Có phải rau củ không? -> false (Loại)
    +) 🥔 -> Có phải rau củ không? -> true (Giữ lại)
    +)  Kết quả trả về: Một mảng mới sạch sẽ chỉ toàn rau củ.
    Cú pháp chặt chẽ

    Hàm bên trong filter chỉ làm đúng một nhiệm vụ duy nhất: Trả về kết quả mang tính chất Đúng/Sai.

    const danhSachSo = [1, 2, 3, 4, 5, 6];

    // Lọc số chẵn: Số nào chia hết cho 2 thì giữ lại const soChan = danhSachSo.filter(num => num % 2 === 0); console.log(soChan); // [2, 4, 6]

    3. reduce() — Đút heo đất (Gom tất cả thành 1 cục)

    Thằng này khó hiểu nhất vì cái tên của nó. reduce nghĩa là "giảm thu gọn". Nó sẽ ép một mảng nhiều phần tử thành đúng một giá trị duy nhất (có thể là 1 con số, 1 chuỗi, hoặc thậm chí là 1 Object tổng hợp).

    • Hình ảnh nhớ lâu (Trò chơi nuôi heo đất): * accumulator (acc): Là con Heo đất của bạn.

      • currentValue (curr): Là số Tiền bạn có mỗi ngày (từng phần tử trong mảng).

      • initialValue: Là số tiền Vốn bạn bỏ sẵn vào heo từ ngày đầu tiên.

    Cơ chế hoạt động từng bước (Nhìn là hiểu)

    Giả sử bạn muốn tính tổng của mảng: const tienMoiNgay = [10, 20, 30]; và bạn bỏ vốn ban đầu vào heo là 0.

    const tongTien = tienMoiNgay.reduce((heoDat, tienHomNay) => {
        return heoDat + tienHomNay;
    }, 0); // 0 chính là số vốn ban đầu bỏ vào heoDat

    Hàm này sẽ chạy 3 vòng tương ứng với 3 phần tử:

    • Vòng 1: heoDat  đang có 0đ. tienHomNay là 10đ. Bạn lấy 0 + 10 = 10đ. Bạn return 10; tức là ôm con heo chứa 10đ này chuyền sang vòng sau.
    • Vòng 2: heoDat nhận vào 10đ. tienHomNay là 20đ. Bạn lấy 10 + 20 = 30đ. Bạn lại return 30; để chuyền con heo đi tiếp.
    • Vòng 3: heoDat đang có 30đ. tienHomNay là 30đ. Bạn lấy 30 + 30 = 60đ. Hết mảng! Kết quả cuối cùng bạn nhận được là con heo chứa 60.
    🔥 Lỗi chí mạng: Nếu bạn quên không viết return heoDat + tienHomNay; ở trong hàm, thì ở vòng tiếp theo, con heo đất sẽ bị biến thành undefined (rỗng tuếch) và code sẽ báo lỗi ngay lập tức. Bạn luôn luôn phải "chuyền heo đất" về cho vòng lặp kế tiếp.

    💡 4 Tip Xương Máu Để Nhớ Lâu, Viết Code Cứng

    1. Tip đặt tên biến: Đừng bao giờ đặt tên biến trong hàm lặp là item hay element một cách vô nghĩa. Hãy đặt tên theo quy tắc Mảng số nhiều -> Phần tử số ít.
    • keywords.map(keyword => ...)
    • posts.filter(post => ...)
    • Đọc lên như một câu tiếng Anh, não bạn sẽ tự động hiểu logic mà không cần cố nhớ.
    2. Nhìn vào đầu ra (Output) để chọn hàm:
    • Cần mảng mới, kích thước y chang mảng cũ, chỉ đổi ruột? ➔ Dùng map.
    • Cần mảng mới, lọc bớt phần tử đi theo điều kiện? ➔ Dùng filter.
    • Cần tính toán gom về 1 kết quả duy nhất? ➔ Dùng reduce.
    3. Tuyệt đối không làm biến đổi mảng gốc: Cả 3 hàm này đều tạo ra một kết quả mới độc lập. Nếu mảng của bạn chứa Object, hãy nhớ quy tắc Tham chiếu ở bài trước: Dùng Spread Operator {...object} bên trong map nếu muốn chỉnh sửa thuộc tính của Object đó để bảo vệ dữ liệu gốc.
    4. Vẽ ra giấy: Khi nào bí logic của reduce, hãy vẽ 2 cột: Cột Heo đất (acc) và cột Phần tử hiện tại (curr). Chạy tay thử 2 vòng là bạn sẽ tự khắc viết được code chuẩn mà không sợ bị loạn.