Mule4 DataWeave Exercise: map, reduce, and pluck
This post guides you step-by-step through a DataWeave exercise demonstrating how to use the reduce, map, valuesOf, splitBy functions, format, and ++ operator.
Join the DZone community and get the full member experience.
Join For FreeUsing the DataWeave exercise below, I'll demonstrate how to use the reduce, map, valuesOf, splitBy functions, format, and ++ operator.
Given Input:
[
{
"empId": "ex12345",
"fullName": "Peter parker",
"street": "Second Ave 46",
"city": "San Francisco",
"state": "veniam",
"postal": "sit",
"country": "Mexico",
"dept": "hr",
"joinedDate": "2021-12-22",
"miles": 68
},
{
"empId": "ex54321",
"fullName": "Joseph charles",
"street": "First Ave 47",
"city": "Bangalore",
"state": "Karnataka",
"postal": "560100",
"country": "India",
"dept": "finance",
"joinedDate": "2021-11-15",
"miles": 49
}
]
Desired Output:
[
{
"firstName": "Peter",
"lastName": "parker",
"AddrWithValuesOf": "San Francisco,veniam,sit,Mexico",
"AddrWithPluck": "San Francisco,veniam,sit,Mexico",
"miles": 68.00,
"DateofJoin": "22-Dec-2021"
},
{
"firstName": "Joseph",
"lastName": "charles",
"AddrWithValuesOf": "Bangalore,Karnataka,560100,India",
"AddrWithPluck": "Bangalore,Karnataka,560100,India",
"miles": 49.00,
"DateofJoin": "15-Nov-2021"
}
]
We can accomplish the desired output by writing the following DataWeave.
DataWeave Code:
%dw 2.0
output application/json
fun nameSplit(name ) = name splitBy " "
---
payload map {
"firstName": nameSplit($.fullName)[0],
"lastName": nameSplit($.fullName)[1],
"AddrWithValuesOf" : valuesOf($)[3 to 6] reduce ($$ ++ "," ++ $),
"AddrWithPluck" : ($ pluck (V,K) -> (V)) [ 3 to 6] reduce ($$ ++ "," ++ $),
"miles" : $.miles as String { format : "0.00" } as Number,
"DateofJoin": $.joinedDate as Date {format: 'yyyy-MM-dd'} as String { format : "dd-MMM-yyyy" }
}
I'll break down the above-mentioned DataWeave code into steps.
Before diving into the code, I recommend that you write and test the code in the DataWeave Playground.
Step 1:
To begin, we should use the map function to loop over the input array of objects and perform operations on each object to return an array. The value (element of an array) and index (index of the element in the array) parameters are used in map functions . If the map function parameters aren't defined, the implicit parameters are "$" (value) and "$$" (index), as shown below.
%dw 2.0
output application/json
---
payload map {
"name": $.fullName,
"street" : $.street,
"index" : $$,
"miles" : $.miles ,
"DateofJoin": $.joinedDate
}
Step 2:
Now we need to use the splitBy function and write a custom function in DataWeave to split the "fullName" field of each object in the array into two fields called "firstName" and "lastName".
- Create a custom function using the keyword "fun". The benefit of doing so is that the logic written in this custom function can be referred to and further used several times throughout the code.
- The splitBy function can be used to split a string into an array of strings based on the matching part (separator) provided as an input parameter, with the separator being removed. The splitBy is the polar opposite of the joinBy. "namesplit" is a custom function that uses the splitBy function with the separator " " (space) as shown below to split "fullName" into "firstName" and "lastName."
%dw 2.0
output application/json
fun nameSplit(name) = name splitBy " "
---
payload map {
"firstName": nameSplit($.fullName)[0],
"lastName": nameSplit($.fullName)[1]
}
Step 3:
- The valuesOf function extracts an array of values from an object's key-value pairs and returns an array with an index value that can be used to filter only the values that are necessary.
%dw 2.0
output application/json
---
payload map {
"AddrWithValuesOf" : valuesOf($)[3 to 6]
}
2. Now that we have the address as an array of strings, we need to convert it to a single string. To do so, we can use the reduction function to concatenate the strings of the array (address) into a single string. "$$" refers to the accumulator, and "$" refers to the array element. "++" operator is used for concatenation.
%dw 2.0
output application/json
---
payload map {
"AddrWithValuesOf" : valuesOf($)[3 to 6] reduce ($$ ++ "," ++ $)
}
Step 4:
Instead of using valuesOf function, Step 3 can be accomplished in a different way. We can use the pluck function to extract values or keys from an object's key-value pairs and return an array of keys or values. We used pluck to extract values and reduce to concatenate them as shown below.
%dw 2.0
output application/json
fun nameSplit(name ) = name splitBy " "
---
payload map {
"AddrWithPluck" : ($ pluck (V,K) -> (V)) [ 3 to 6] reduce ($$ ++ "," ++ $)
}
Step 5:
This is the final step in achieving the desired output. We need to format data in this stage, to format "miles" as a number with two decimals, use the following syntax: { format : "0.00" }.
%dw 2.0
output application/json
---
payload map {
"miles" : $.miles as String { format : "0.00" } as Number
}
To format "DateofJoin" into the desired date format, we must first declare the existing date format, which is { format: 'yyyy-MM-dd' } followed by the desired date { format : "dd-MMM-yyyy" }.
%dw 2.0
output application/json
---
payload map {
"DateofJoin": $.joinedDate as Date {format : 'yyyy-MM-dd'} as String { format : "dd-MMM-yyyy" }
}
DataWeave Code (Consolidation of All Steps Code):
%dw 2.0
output application/json
fun nameSplit(name ) = name splitBy " "
---
payload map {
"firstName": nameSplit($.fullName)[0],
"lastName": nameSplit($.fullName)[1],
"AddrWithValuesOf" : valuesOf($)[3 to 6] reduce ($$ ++ "," ++ $),
"AddrWithPluck" : ($ pluck (V,K) -> (V)) [ 3 to 6] reduce ($$ ++ "," ++ $),
"miles" : $.miles as String { format : "0.00" } as Number,
"DateofJoin": $.joinedDate as Date {format: 'yyyy-MM-dd'} as String { format : "dd-MMM-yyyy" }
}
Opinions expressed by DZone contributors are their own.
Comments