Hàm reduce() trong DataWeave 1 và 2 là hàm giúp chúng ta có thể thao tác trên các phần tử của một array và output ra kiểu dữ liệu mà chúng ta muốn.
Để làm được điều này, tham số của hàm reduce() bao gồm item trong array mà chúng ta sẽ thao tác và tham số thứ 2 accumulator sẽ lưu trữ và định nghĩa kiểu dữ liệu mà chúng ta muốn trả về. Cấu trúc của hàm reduce() được viết theo kiểu Lambda Expression từ Java 8 như sau:
1 |
<input> reduce (item, acc) -> <...> |
Trong đó, <input> là array mà chúng ta sẽ thao tác. Hàm reduce() sẽ loop qua tất cả các item của array, và đối với mỗi item, nó sẽ thực hiện thao tác được định nghĩa trong phần nội dung của Lambda Expression. Giá trị của tham số acc, nếu chúng ta không định nghĩa giá trị ban đầu cho nó thì giá trị của nó sẽ bắt đầu từ giá trị của phần tử đầu tiên của array và chúng ta có thể định nghĩa kiểu dữ liệu trả về sử dụng tham số acc này ví dụ như sau:
1 |
acc = {} |
cho đối tượng Object,
1 |
acc = [] |
cho mảng và
1 |
acc = "" |
cho String.
Ví dụ mình có array như sau:
1 |
var arr = [1, 2, 3, 4] |
Nếu chúng ta ko thực hiện thao tác gì:
1 2 3 4 5 6 7 8 9 |
%dw 2.0 output application/json var arr = [1, 2, 3, 4] --- { item: arr reduce ((item, acc) -> item), acc: arr reduce((item, acc) -> acc) } |
thì giá trị cuối cùng tham số item sẽ là giá trị của phần tử cuối cùng trong array, và giá trị cuối cùng của tham số acc sẽ là giá trị của phần tử đầu tiên trong array.
Nếu các bạn muốn tính tổng, nối chuỗi, đảo ngược chuỗi thì có thể viết như sau:
1 2 3 4 5 6 7 8 9 10 |
%dw 2.0 output application/json var arr = [1, 2, 3, 4] --- { sum: arr reduce ((item, acc) -> acc + item), concat: arr reduce((item, acc) -> acc ++ item), reverse: arr reduce((item, acc) -> item ++ acc) } |
Kết quả:
Việc chúng ta định nghĩa thao tác trước hoặc sau tham số acc cộng với việc định nghĩa output trong tham số này sẽ giúp chúng ta có được kết quả mong muốn, DataWeave sẽ dựa vào các định nghĩa này để trả về kết quả.
Mặc định thì như mình nói ở trên, giá trị của tham số acc sẽ là giá trị của phần tử đầu tiên trong mảng, nhưng nếu các bạn set cho nó một giá trị đầu tiên, ví dụ như:
1 2 3 4 5 6 7 8 |
%dw 2.0 output application/json var arr = [1, 2, 3, 4] --- { sum: arr reduce ((item, acc = 2) -> acc + item) } |
thì giá trị ban đầu của tham số acc sẽ là giá trị này.
Như ví dụ trên, mình gán cho tham số acc một giá trị ban đầu là 2 nên khi tính toán tổng các phần tử của mảng trên, giá trị cuối cùng sẽ là 12:
Nếu các bạn có một đối tượng tương tự như sau:
1 2 3 4 |
var students = [ { "name": "Khanh", "age": 32 }, { "name": "Quan", "age": 25 } ] |
và các bạn muốn output là một mảng của tên sinh viên thì các bạn có thể code như sau:
1 2 3 4 5 6 7 8 9 10 11 |
%dw 2.0 output application/json var students = [ { "name": "Khanh", "age": 32 }, { "name": "Quan", "age": 25 } ] --- { names: students reduce ((item, acc=[]) -> acc + item) } |
Ở đây, chúng ta đang định nghĩa kiểu dữ liệu trả về cho tham số acc là một mảng nên khi output các bạn sẽ thấy kết quả như sau:
Các bạn cũng có thể sử dụng các ký tự $ để thay thế cho tham số item của mảng và $$ thay thế cho tham số acc khi sử dụng hàm reduce tương tự như hàm pluck() trong DataWeave.
Ví dụ chúng ta cũng có thể viết code sử dụng $ và $$ như sau:
1 2 3 4 5 6 7 8 |
%dw 2.0 output application/json var arr = [1, 2, 3, 4] --- { sum: arr reduce ($$ + $) } |
Kết quả vẫn vậy: