Sử dụng map, filter và reduce trong Javascript như nào cho đúng?

Bài viết được sự cho phép của tác giả Tống Xuân Hoài

Vấn đề

Dữ liệu được lưu trữ trong cơ sở dữ liệu thường phải được chuẩn hóa để giảm dung lượng và tăng tốc độ truy vấn, Vì thế sau khi lấy ra thường phải qua nhiều phép biến đổi dữ liệu thì mới có thể dùng để xử lý logic tiếp được.

Lập trình FE, đặc biệt là lập trình dựa trên những Framework hiện đại như Angular, React, Vue… việc tạo ra những đối tượng để lưu trạng thái (state) của ứng dụng đòi hỏi khả năng xử lý dữ liệu nhiều hơn nữa. Bởi vì những trạng thái này là thay đổi liên tục phụ thuộc vào logic hiển thị và thao tác người dùng.

Những dữ liệu trên thông thường được lưu trữ trong Object hay Array, chính vì thế kể từ ES5 tung ra bộ ba mapfilter và reduce để giúp chúng ta xử lý dữ liệu mảng một cách hữu ích hơn rất nhiều.

  15 ví dụ sử dụng map, reduce và filter

  Một vài ứng dụng hay ho của reduce

map, filter và reduce

Hàm map duyệt qua mảng, và trả về một mảng có số lượng phần tử bằng đúng với số lượng phần tử mảng ban đầu. Các phần tử được trả về thông qua return.

Ví dụ:

const arr = [1, 2, 3];
const arr2 = arr.map(function (item) {
  return item + 1;
});
// [2, 3, 4]

Hàm filter cũng duyệt qua mảng, trả về một mảng mới với các phần tử thỏa mãn một điều kiện true/false.

Ví dụ:

const arr = [1, 2, 3];
const arr2 = arr.map(function (item) {
  return item > 1;
});
// [2, 3]

Reduce duyệt qua mảng, thực hiện tính toán trong hàm callback.

Ví dụ:

const arr = [1, 2, 3];
const sum = arr.reduce(function(accumulator, currentValue) {
  return accumulator + currentValue;
}, 0);

reduce là hàm nâng cao nên độ khó cao hơn khi bắt đầu. Tuy nhiên bạn có thể nhanh chóng sử dụng thành thạo chúng thông qua một vài ví dụ tại Reduce Syntax.

Cú pháp đầy đủ của reduce là:

reduce((accumulator, currentValue, currentIndex, array) => {
    /* … */
}, initialValue)

Với accumulator là giá trị tích lũy, giá trị tích lũy ban đầu sẽ bằng initialValuecurrentValue là phần tử trong mảng ở lần lặp hiện tại, tương tự currentIndex là vị trí phần tử và array là mảng ban đầu. initialValue là giá trị khởi tạo.

Đầu ra của map và filter luôn luôn là một mảng, chính vì thế nếu thấy chúng xuất hiện thì chắc chắn đầu ra phải là một thứ “có thể lặp”. Điều này rất quan trọng, vì nó giúp tạo nên tính cam kết và khả năng liền mạch trong khi kết hợp nhiều hàm với nhau khi xử lý.

const arr = [];
arr.map().filter().map()...

Bạn có thể dùng ngay filter ngay sau map mà không lo lắng rằng kết quả của map trả về nullundefined… bất kì thứ gì đó mà “không thể lặp” qua.

Việc làm Javascript lương cao trên TopDev

Một vài trường hợp sử dụng

Có rất nhiều trường hợp bạn cần dùng đến bộ 3 này, khi nào cần biến thêm/thắt hay thay đổi thuộc tính trong mảng thì dùng map, khi nào cần lọc dữ liệu trong mảng thì dùng filter còn khi nào muốn trả về một kết quả cần tổng hợp từ mảng thì dùng reduce.

Tóm lại là khi làm việc với dữ liệu là mảng thì hãy nghĩ đến bộ ba này đầu tiên, dần dần bạn sẽ biết cách dùng thành thạo. Điều này giúp bạn viết ra đoạn mã ngắn gọn hơn.

Một số trường hợp tiêu biểu mình sử dụng là trong xử lý dữ liệu nhận từ API.

Dữ liệu nhận từ API về là dữ liệu “thô”, gọi như thế bởi vì cần qua một vài bước xử lý nữa thì mới thành dữ liệu “chuẩn” để hiển thị lên trang web được, lúc đó chúng ta có thể sử dụng mapfilter hoặc reduce để thêm, bớt, sửa đổi hay lọc dữ liệu trong mảng.

Thứ hai là dữ liệu được lấy ra trong cơ sở dữ liệu (database). Đây là dữ liệu được tối ưu hóa để lưu trữ vì thế trong lúc xử lý những logic bạn vẫn cần phải thêm thắt nhiều nữa mới ra dữ liệu chuẩn. Một ví dụ tiêu biểu cho trường hợp này là định dạng lại dữ liệu trả về cho client thông qua API.

Thứ ba là dữ liệu tạo ra để phục vụ cho mục đích xử lý logic. Loại dữ liệu này được tạo ra trong quá trình xử lý logic của bài toán nào đó. Trong quá trình tính toán thì việc biến đổi dữ liệu có thể xảy ra thường xuyên. Việc vận dụng mapfilter và reduce thành thạo có thể giúp bạn xử lý vấn đề với số lượng mã ít hơn.

Ngoài ra, có rất nhiều hàm mà Javascript cung cấp khi thao tác với mảng như findfindIndexindexOf… Những hàm này hoàn toàn có thể thay thế bởi bộ ba mapfilter và reduce. Tuy nhiên nếu có thể hãy sử dụng chúng để tăng tính minh bạch cho mã.

Tổng kết

Bộ ba mapfilter và reduce là trợ thủ đắc lực khi làm việc với dữ liệu mảng. Biết cách vận dụng chúng phù hợp giúp bạn giảm được thời gian viết mã đồng thời giúp mã ngắn gọn hơn.

Bài viết gốc được đăng tải tại 2coffee.dev

Có thể bạn quan tâm:

Tìm việc làm IT mới nhất trên TopDev