CÁCH DÙNG MAP, REDUCE, FILTER TRONG JAVASCRIPT

06/10/2021 19
map reduce filter
CODEWELL

Khi làm việc trên các dự án Javascript, chúng ta thường gặp những tình huống cần phải thực hiện một số thao tác với dữ liệu. Ví dụ như lọc kết quả từ 1 list data hoặc thao tác với một thuộc tính của tất cả các phần tử trong 1 list data. Bạn có thể sử dụng vòng lặp for-loop để lấy được kết quả mong muốn, tuy nhiên trong 1 số trường hợp sử dụng thì code sẽ trở nên phình to ra và khá lộn xộn.

Hầu hết các trường hợp có thể dễ dàng lấy được dữ liệu bằng cách sử dụng map, reduce và filter. Code của bạn sẽ trở nên đẹp hơn và dễ đọc hơn. Bên cạnh đó, trong functional programming thì các high order functions như map, reduce, filter sẽ tương tác trên 1 mảng mới, và như vậy nó sẽ ko làm thay đổi giá trị của mảng gốc.

Trong bài viết này, hãy cùng CO-WELL khám phá cách dùng của 3 hàm này nhé!

 

Các trường hợp có thể sử dụng hàm Map, Reduce, Filter

Để biết khi nào cần dùng hàm nào, hãy tuân theo những quy tắc dưới đây nhé:

  • Nếu tôi có 1 mảng và tôi muốn xử lý từng phần tử của mảng theo cùng 1 cách và trả về một mảng có số lượng phần tử đúng bằng số lượng phần tử của mảng ban đầu thì tôi sẽ sử dụng map.
  • Nếu tôi đã có 1 mảng nhưng tôi chỉ muốn lấy các phần tử theo 1 tiêu chuẩn nhất định, tôi sử dụng filter.
  • Nếu tôi đã có 1 mảng và tôi muốn sử dụng các giá trị trong mảng để tạo ra thứ hoàn toàn mới, tôi sử dụng reduce.

Các quy tắc trên có vẻ hơi mơ hồ nên chúng ta sẽ xem các ví dụ bên dưới để hiểu rõ hơn nhé!

 

    const animals = [

        {

            "name": "cat",

            "size": "small",

            "weight": 5

        },

        {

            "name": "dog",

            "size": "small",

            "weight": 10

        },

        {

            "name": "lion",

            "size": "medium",

            "weight": 150

        },

        {

            "name": "elephant",

            "size": "big",

            "weight": 5000

        }

    ]

 

Hàm map()

Trường hợp chúng ta muốn có một mảng mới chứa tên các con vật từ mảng đã có ở trên.

Nếu sử dụng for-loop chúng ta sẽ làm như sau:

   let animal_names = [];

 

    for (let i = 0; i < animals.length; i++) {

        animal_names.push(animals[i].name);

     }

 

Nếu dùng hàm map():

    let animal_names = animals.map((animal, index, animals) => {

        return animal.name

    })

Hàm map() nhận vào 3 tham số cho hàm callback:

  • Phần tử hiện tại của mảng
  • Index của phần tử hiển tại
  • Mảng đầu vào

Ưu điểm so với for-loop:

  • Không cần quản lý trạng thái vòng lặp
  • Không cần sử dụng index để truy cập phần tử của mảng
  • Không cần tạo thêm 1 mảng mới(animal_names) rồi thêm giá trị vào đó

1 điểm cần lưu ý khi sử dụng map là bắt buộc phải sử dụng return. Nếu không sử dụng thì mảng trả lại sẽ chỉ chứa các giá trị undefined

 

Hàm filter()

Trường hợp chúng ta chỉ muốn lấy ra một mảng gồm những con vật nhỏ.

Nếu sử dụng for-loop chúng ta sẽ làm như sau:

    let small_animals = [];

 

    for (let i = 0; i < animals.length; i ++) {

        if (animals[i].size === "small") {

            small_animals.push(animals[i])

        }

    }

Nếu dùng hàm filter():

let small_animals = animals.filter((animal) => {

    return animal.size === "small"

})

 

Hàm callback của filter cũng nhận vào những tham số như hàm map. Nhưng trong trường hợp này chúng ta không dùng đến 2 tham số Index của phần tử hiển tại và Mảng đầu vào nên chúng ta sẽ không đưa nó vào hàm callback. Chúng ta cũng cần sử dụng return để trả về các giá trị cho mảng đầu ra. Tuy nhiên cần lưu ý đối với hàm filter chúng ta sẽ trả về giá trị boolean (điều kiện cần fillter). Nếu không có làm phần này thì hàm sẽ luôn trả về false

 

Hàm reduce()

Trường hợp chúng ta cần tính tổng khối lượng các con vật.

Nếu sử dụng for-loop chúng ta sẽ làm như sau:

    let total_weight = 0;

 

    for (let i = 0; i < animals.length; i++) {

        total_weigth += animals[i].weight

    }

Nếu dùng hàm reduce():

    let total_weight = animals.reduce((weight, animal, index, animals) => {

        return weight += animal.weight

    }, 0)

 

Với hàm reduce(), các tham số truyền vào sẽ khác 1 chút so với 2 hàm kể trên:
Giá trị hiện tại của biến ta muốn trả ra khi kết thúc hàm(trong ví dụ trên là total_weight). Chúng ta cần gán giá trị ban đầu cho biến này (trong ví dụ trên là 0)

  • Phần tử hiện tại của mảng.
  • Indexcủa phần tử hiển tại
  • Mảng đầu vào

Những lợi ích khi sử dụng reduce() cũng tương tự như map(), filter() làm cho code ngắn hơn, dễ đọc hơn. Chúng ta vẫn sẽ phải sử dụng return. Lần này sẽ trả về giá trị cho biến total_weight, giá trị này sẽ được cộng dồn sau mỗi lần lặp và gán vào tham số đầu tiên của hàm callback(weight)

 

Kết

Thông qua những ví dụ trên, CO-WELL Asia hy vọng bạn đã hiểu rõ hơn về cách dùng map, filter và reduce. Các hàm này sẽ còn hữu dụng hơn khi code hoặc data của bạn trở nên phức tạp. Các bạn có thể sử dụng 3 hàm này thường xuyên hơn để code trở nên sạch, dễ đọc và dễ bảo trì hơn nhé.

 

Phạm Phú Nghĩa – CO-WELL Asia