Bạn đã bao giờ viết một vòng lặp for để lặp lại mảng để lấy [các] giá trị từ nó chưa? . Trong bài viết này, chúng tôi sẽ không tập trung vào hai phần sau, vì vậy hãy nói về giảm
Như tài liệu đã nói, reduce[] thực thi hàm rút gọn trên từng phần tử của mảng. Bộ giảm tốc là một hàm lấy bộ tích lũy [là kết quả tạm thời] và giá trị hiện tại từ phép lặp. Nó làm những gì nó cần với chúng và giá trị được trả về trở thành bộ tích lũy mới. Khi chúng ta đến cuối mảng, bộ tích lũy được trả về do kết quả của hàm rút gọn. Điều đáng nói là rút gọn cũng là cốt lõi của nhiều ngôn ngữ chức năng mà nó thường được tìm thấy dưới tên gấp hoặc tổng hợp. Đó là lý do tại sao cách sử dụng reduce tốt nhất là khi nó có thể cung cấp một sự thay thế đơn giản cho vòng lặp for theo cách tinh tế và thiết thực thay vì với mọi vòng lặp có thể
Theo MDN, cú pháp như sau
arr.reduce[callback[ accumulator, currentValue, [, index[, array]] ][, initialValue]]
Cuộc gọi lại là một hàm giảm tốc và như chúng ta đã nói, nó lấy bộ tích lũy và giá trị hiện tại từ phép lặp. Ngoài ra, chúng ta cũng có thể lấy chỉ mục của phần tử hiện tại và mảng nguồn, nhưng hai phần tử này không được sử dụng thường xuyên. Ngoài ra, chúng tôi có thể xác định giá trị bộ tích lũy ban đầu của mình trong initValue. Nếu chúng tôi không cung cấp nó, giá trị đầu tiên từ một mảng sẽ trở thành giá trị ban đầu
Điều đáng chú ý là còn có hàm reduceRight[]. Nó làm điều tương tự nhưng theo hướng ngược lại bằng cách bắt đầu từ cuối mảng
ví dụ sử dụngĐủ lý thuyết. Hãy đến với phần thực hành. Tại đây, bạn sẽ tìm thấy một vài ví dụ về cách sử dụng reduce cùng với lời giải thích về cách thực hiện và lý do tại sao nó hoạt động. Bạn không nên coi tất cả những điều này như một giải pháp tiếp theo cho từng vấn đề này, mà hơn thế nữa, hãy coi đó là một lời trêu ghẹo trí não và một cách để giảm thiểu
Tổng/hiệu/tích/thương của các phần tử
Trường hợp sử dụng giảm phổ biến nhất và có lẽ là trường hợp duy nhất không gây tranh cãi. Mã ở đây rất đơn giản
var sum = array.reduce[[acc, val] => acc + val]; var diff = array.reduce[[acc, val] => acc - val]; var product = array.reduce[[acc, val] => acc * val]; var quotient = array.reduce[[acc, val] => acc / val];
Bởi vì acc luôn chứa một giá trị trước đó trong giá trị đầu tiên của lần lặp đầu tiên, chúng ta có thể nhận được kết quả một cách an toàn chỉ bằng cách thực hiện một thao tác thích hợp với giá trị hiện tại.
Làm phẳng một mảng
Một trường hợp sử dụng phổ biến khác, nhưng nó hơi lỗi thời vì chúng ta đã có hàm flat[]. Tuy nhiên, nếu bạn muốn xem cách thực hiện theo cách truyền thống bởi vì, e. g. , bạn đang viết cho Internet Explorer 11, đây là mã
var flatArray = array.reduce[[acc, val] => acc.concat[val], []];
Bộ tích lũy của chúng tôi bắt đầu với một mảng trống và sau đó chúng tôi sẽ liên kết một mảng lồng nhau hiện tại với nó. Theo cách này, như kết quả cuối cùng, chúng ta có được mảng phẳng. Chỉ cần nhớ, mã này chỉ hoạt động cho một cấp độ lồng nhau
ống chức năng
Đường ống chức năng, nói một cách đơn giản, là sự hợp nhất của nhiều chức năng hoạt động trên kết quả của chúng. Bạn bắt đầu với hàm đầu tiên và nó trả về kết quả trở thành đối số cho hàm tiếp theo, hàm này trả về kết quả và cứ tiếp tục như vậy cho đến khi chúng ta đến hàm cuối cùng. Điều đáng biết là khi chúng ta sử dụng chức năng đường ống và cung cấp cho nó một số chức năng mà chúng ta muốn chạy, nó cũng sẽ trả về cho chúng ta một hàm chứ không phải giá trị. Đây là cách chúng ta có thể làm điều đó với giảm
var pipe = [...functions] => value => functions.reduce[[acc, func] => func[acc], value];
Làm thế nào nó hoạt động? . Nó trả về một hàm nhận một giá trị và giảm các hàm được cung cấp ban đầu, chạy từng hàm và lấy giá trị trả về cho bộ tích lũy. Tôi biết nó có thể hơi khó hiểu, vì vậy đây là một ví dụ sử dụng
var add2AndStringify = pipe[x => x + 2, x => '' + x] add2AndStringify[10]; // result: "12"
Sắp xếp
Đây là cách sử dụng reduce tồi tệ nhất, nhưng vẫn là một cách thú vị. Đó là lý do tại sao tôi muốn chia sẻ nó với bạn. Tất nhiên, tôi không khuyên bạn nên sử dụng nó. Thay vào đó, bạn nên sử dụng sort[] vì nó nhanh hơn, nhưng nó phục vụ mục đích giáo dục. Nó gần như không phải là cách tối ưu
var sortedArray = array.reduce[[acc, val] => [...acc.filter[x => x x > val]], []];
Nó hoạt động theo cách mà chúng tôi đang tạo một mảng mới cho mọi giá trị. Trước tiên, chúng tôi cung cấp cho tất cả các phần tử nhỏ hơn hoặc bằng nhau, để đảm bảo tính ổn định của thuật toán, đến dòng điện, sau đó là dòng điện và các phần tử còn lại. Nếu bạn biết thuật toán sắp xếp chèn, nó sẽ nghe quen thuộc với bạn. Tuy nhiên, vui lòng không sử dụng nó trong các dự án thực tế, phi giáo dục
Chúng ta có nên sử dụng giảm?Đó là một câu hỏi khó trả lời vì nó phụ thuộc vào trường hợp sử dụng của bạn. Như bạn có thể thấy trong các ví dụ trên, đôi khi chúng tôi đã đơn giản hóa mã, nhưng mã có thể không đọc được trong các trường hợp khác
Ưu tiên của chúng tôi trong mã hóa là làm cho mã có thể đọc được đối với mọi nhà phát triển khác. Khi làm việc theo nhóm, điều cần thiết là tạo một đoạn mã dễ hiểu thay vì viết những đoạn mã lộn xộn khó hiểu mà chỉ tác giả của nó mới có thể đọc được
Một điều khác bạn nên cân nhắc trước khi sử dụng reduce là liệu chức năng này đã được triển khai theo cách đơn giản hơn, thậm chí có thể tốt hơn hay chưa. Không đáng để viết một cái gì đó từ đầu nếu nó đã được thực hiện, đặc biệt nếu nó nằm trong thư viện tiêu chuẩn của một ngôn ngữ