I have a flat array of Customers, and could not find an appropriate Method (Way) to Unflatten it so that each Customer & his Age becomes Nested.
INPUT
{
"1st Customer": "2216",
"Age": "90",
"2nd Customer": "2231",
"Age": "90",
"3rd Customer": "2249",
"Age": "120",
"4th Customer": "2302",
"Age": "150",
"5th Customer": "",
"Age": ""
}
OUTPUT
{
"customers": [
{
"CustomerSeq": "1",
"CustomerID": "2216",
"Age": 90,
},
{
"CustomerSeq": "2",
"CustomerID": "2231",
"Age": 90,
},
{
"CustomerSeq": "3",
"CustomerID": "2249",
"Age": 120,
},
{
"CustomerSeq": "5",
"CustomerID": "2302",
"Age": 150,
}
]
}
Thanks a lot, Alex
The divideBy is exactly what I was looking for
The Solution [including the removal of the empty values]:
%dw 2.0
output application/json
import * from dw::core::Objects
---
customers:
((payload filterObject ((value, key, index) -> value != "")) divideBy 2) map (
(pCustomer, indexOfpCustomer) -> {
CustomerSeq:indexOfpCustomer+1,
CustomerID: pCustomer[0],
Age: pCustomer[1]
})
There is a good function for it in Mule: divideBy.
It will split an array of your values from the object, and then the requested object could be created:
%dw 2.0
var x={
"1st Customer": "2216",
"Age": "90",
"2nd Customer": "2231",
"Age": "90",
"3rd Customer": "2249",
"Age": "120",
"4th Customer": "2302",
"Age": "150",
"5th Customer": "",
"Age": ""
}
var keys=x pluck $$
var values=x pluck $
import * from dw::core::Arrays
output application/dw
---
values divideBy 2 map (item,index) ->
{
CustomerSeq:index+1,
CustomerID:item[0],
Age:item[1]
}
output
[
{
CustomerSeq: 1,
CustomerID: "2216",
Age: "90"
},
{
CustomerSeq: 2,
CustomerID: "2231",
Age: "90"
},
{
CustomerSeq: 3,
CustomerID: "2249",
Age: "120"
},
{
CustomerSeq: 4,
CustomerID: "2302",
Age: "150"
},
{
CustomerSeq: 5,
CustomerID: "",
Age: ""
}
]
Related
Hopefully this is the last of my questions related to this and this
The earlier questions were related to generating XML payload while this query is around generating JSON o/p in a specific format...
Thanks to #Harshank and #sudhish_s was able to make some progress with XML o/p. However I am not able to figure out how to go about json o/p
Here is the input payload ( have limited it to three rows / json objects but could be in thousands)
[
{
"gp": "S1",
"gp_eye_colour": "blue",
"gp_name" : "John",
"parent": "S1",
"parent_eye_colour" : "blue",
"parent_name" : "Sam",
"child": "C1",
"child_eye_colour" : "black",
"child_name" : "C1-name"
},
{
"gp": "S1",
"gp_eye_colour": "blue",
"gp_name" : "John",
"parent": "P1",
"parent_eye_colour" : "blue",
"parent_name" : "Don",
"child": "C1",
"child_eye_colour" : "brown",
"child_name" : "C1-name"
} ,
{
"gp": "S2",
"gp_eye_colour": "blue",
"gp_name" : "David",
"parent": "P2",
"parent_eye_colour" : "blue",
"parent_name" : "Martha",
"child": "C1",
"child_eye_colour" : "brown",
"child_name" : "C1-name"
}
]
Desired o/p is as below :
{
"S2_blue": {
"code": "S2",
"eyeColour": "blue",
"name": "David",
"hierarchy": [
{
"code": "P2",
"eyeColour": "blue",
"name": "Martha",
"hierarchy": [
{
"code": "C1",
"eyeColour": "brown",
"name": "C1-name",
"hierarchy": []
}
]
}
]
},
"S1_blue": {
"code": "S1",
"eyeColour": "blue",
"name": "John",
"hierarchy": [
{
"code": "P1",
"eyeColour": "blue",
"name": "Don",
"hierarchy": [
{
"code": "C1",
"eyeColour": "brown",
"name": "C1-name",
"hierarchy": []
}
]
},
{
"code": "C1",
"eyeColour": "black",
"name": "C1-name",
"hierarchy": []
}
]
}
}
Similar rules need to apply :
Its a Grandparent >> Parent >> Child hierarchy
If Grandparent and Parent share same characteristics (gp == parent and gp_eye_colour == parent_eye_colour then skip parent and directly include child(ren)
( as an example parent Sam is excluded since John (gp) has the same value for gp and eye_colour
Don is not exluded ( same rule as above )
Using the solutions provided to the earlier asked questions - I came up with the following code:
%dw 2.0
output application/json
var hierarchy = ["gp", "parent", "child"]
fun getDirectGeanologies(records, level) = do {
var hLevel = hierarchy[level]
var xyz = if(level == 0)
(records groupBy ((item, index) -> item.gp ++ "_" ++ item.gp_eye_colour) )
else if(level == 1)
(records groupBy ((item, index) -> item.parent ++ "_" ++ item.parent_eye_colour))
else
(records groupBy ((item, index) -> item.child ++ "_" ++ item.child_eye_colour))
---
xyz mapObject ((children, code) ->
(code): {
code: children[0][hLevel],
eyeColour: children[0][hLevel ++ "_eye_colour"],
name: children[0][hLevel ++ "_name"],
hierarchy:
if (level == sizeOf(hierarchy) - 1) [] // if level = 2 ( child stop recursion)
else do {
var nextLevel = level + 1
var nextGen = if(nextLevel == 1)(children groupBy ((item, index) -> item.parent ++ "_" ++ item.parent_eye_colour)) else (children groupBy ((item, index) -> item.child ++ "_" ++ item.child_eye_colour))
---
nextGen mapObject ((nextGenChildren, nextGenCode) ->
if (nextGenCode == code)
getDirectGeanologies (nextGenChildren, nextLevel + 1 ) // skip parent
else
getDirectGeanologies (nextGenChildren, nextLevel)
)
}
}
)
}
---
getDirectGeanologies(payload,0)
However it is not producing desired o/p :
{
"S1_blue": {
"code": "S1",
"eyeColour": "blue",
"name": "John",
"hierarchy": {
"C1_black": {
"code": "C1",
"eyeColour": "black",
"name": "C1-name",
"hierarchy": [
]
},
"P1_blue": {
"code": "P1",
"eyeColour": "blue",
"name": "Don",
"hierarchy": {
"C1_brown": {
"code": "C1",
"eyeColour": "brown",
"name": "C1-name",
"hierarchy": [
]
}
}
}
}
},
"S2_blue": {
"code": "S2",
"eyeColour": "blue",
"name": "David",
"hierarchy": {
"P2_blue": {
"code": "P2",
"eyeColour": "blue",
"name": "Martha",
"hierarchy": {
"C1_brown": {
"code": "C1",
"eyeColour": "brown",
"name": "C1-name",
"hierarchy": [
]
}
}
}
}
}
}
The issues here are :
hierarchy inside gp should be an array but I am getting a object
Not 100% sure but because of above problem rather than having objects inside an array against hierarchy I am getting an object with key as parent/child and eye colour ( Ex : C1_black , P1_blue etc )
So not really sure how to get this part and I am having a tough time to visualise the recursive behaviour
Thanks in advance and once again really appreciate the help already provided by #Harshank and #sudhish_s
I have answered this in mulesoft help forum. LInk MuleSoft Help Forum link
I'm looking for an output similar to this one below where i want to groupBy costomer and orderid.
Input:
[
{
"item": 621,
"orderid": "ON22",
"qty": 45.0,
"customer": "610",
"date": "1988-08-13"
},
{
"item": 63,
"orderid": "ON2234",
"qty": 7,
"customer": "813",
"date": "2001-08-13"
}
]
Desired output:
[
{
"customer":"813",
"data":[
{
"item":63,
"qty":7,
"orderid":"ON2234",
"date":"2001-08-13"
}
]
},
{
"customer":"610",
"data":[
{
"item": 621,
"qty": 45.0,
"orderid": "ON22",
"date": "1988-08-13"
}
]
}
]
You can simply map the default output of your groupBy result since your output does not require any additional logic.
%dw 2.0
output application/json
---
payload groupBy $.customer pluck ((customerOrders, customerId) -> {
customer: customerId as String,
data: customerOrders
})
My input is
[
{
"Id": 5,
"FirstName": "ALEX",
"LastName": "JOHNSON"
},
{
"Id": 4,
"FirstName": "BOB",
"LastName": "BROWN"
},
{
"Id": 2,
"FirstName": "JANE",
"LastName": "DOE"
},
{
"Id": 1,
"FirstName": "JOHN",
"LastName": "SMITH"
},
{
"Id": 6,
"FirstName": "JOHN",
"LastName": "WILKINS"
},
{
"Id": 3,
"FirstName": "TIMOTHY",
"LastName": "WALTERS"
}
]
Output I want is a string concatenating all the FirstName values in the order in which they are listed in the input
"ALEX, BOB, JANE, JOHN, JOHN, TIMOTHY"
I'm new to Dataweave and not sure how to do this
Thanks in advance
You can also try it with the use of descendant selector
%dw 2.0
output application/json
---
payload..FirstName joinBy ","
One way to do it is to first map each element into the FirstName value only then use the joinBy() function to concatenate them separate by a comma:
%dw 2.0
output application/json
---
payload map $.FirstName joinBy ", "
You can alternatively use the reduce() function.
I have gone through karate documentation and questions asked on stack overflow. There are 2 json arrays under resp.response.data. I am trying to retrieve and assert "bId": 81 in below json from the resp.response.data[1] but I get this missing property error while retrieving id value 81. Could you please help if I am missing something ?
* def resp =
"""
{
"response": {
"data": [
{
"aDetails": {
"aId": 15,
"aName": "Test",
"dtype": 2
},
"values": [
{
"bId": 45,
"value": "red"
}
],
"mandatory": false,
"ballId": "1231231414"
},
{
"aDetails": {
"aId": 25,
"aName": "Description",
"dtype": 2
},
"values": [
{
"bId": 46,
"value": "automation"
},
{
"bId": 44,
"value": "NESTED ARRAY"
},
{
"bId": 57,
"value": "sfERjuD"
},
{
"bId": 78,
"value": "zgSyPdg"
},
{
"bId": 79,
"value": "NESTED ARRAY"
},
{
"bId": 80,
"value": "NESTED ARRAY"
},
{
"bId": 81,
"value": "NESTED ARRAY"
}
],
"mandatory": true,
"ballId": "1231231414"
}
],
"corId": "wasdf-242-efkn"
}
}
"""
* def expectedbID=81
* def RespValueId = karate.jsonPath(resp, "$.data[1][?(#.bId == '" + expectedbID + "')]")
* match RespValueId[0] == expectedbID
Maybe you are over-complicating things ?
* match resp.response.data[1].values contains { bId: 81, value: 'NESTED ARRAY' }
I am defining the global function for payload but in the dataweave 1.0 I am not able to do the task.
I have to define a separate global dataweave file where I have to add the conditions for payload like if gender== "male" then title= "mr."
How can I perform the task. I have added my input and expected payload.
input payload:
{
"persons": [
{
"name": "Devendra",
"gender": "male",
"age": 25
},
{
"name": "aman",
"gender": "male",
"age": 16
}
]
}
expected payload:
{
"persons": [
{
"title": "MR.",
"name": "Devendra",
"gender": "male",
"age": 25,
"adult": true
},
{
"title": "MS.",
"name": "Seema",
"gender": "female",
"age": 16,
"adult": false
}
]
}
In Dataweave 1 you can define a global library by creating a dwl file in src/main/resources like so:
src/main/resources/dw/myFunctions.dwl:
%dw 1.0
%function titleForGender(gender)("mr" when gender=="male" otherwise "whoKnows?")
---
{
"titleForGender": titleForGender
}
This script creates a global function and then exposes it in the body so its available to the other script.
Then in your main dw transformation something like this:
%dw 1.0
%output application/json
%var sampleData={persons:[{name:"Devendra", gender:"male",age:25}, {name:"aman", gender:"male",age:16}]}
%var lib = readUrl("classpath://dw/myfunctions.dwl")
---
persons: sampleData.persons map {
"person": $ ++ {title: lib.titleForGender($.gender)}
}
It uses readUrl to read in the function from the global file as var lib and then uses it when mapping the person data, passing in the gender to the function and getting the title returned from the function.
This outputs:
{
"persons": [
{
"person": {
"name": "Devendra",
"gender": "male",
"age": 25,
"title": "mr"
}
},
{
"person": {
"name": "aman",
"gender": "male",
"age": 16,
"title": "mr"
}
}
]
}