0
votes

(PS: Following is a simplified example to explain my requirement. the real data is much more huge and complex.)

I have a list of rows which would serve as line items. i need to dynamically group these line items and build a header for each group. if you can follow the structure.

1: input structure output structure

I have implemented the logic but it is only considering alternative rows v.i.z array [0],1,[4],[6]. 1,3,5 etc are missing

here is my logic in data weaver transform message :

%dw 2.0
output application/java
---
flatten(payload map ((item, index) ->
[{
"type":"header",
"name":"",
"code":payload[index].code,
"status":payload[index].status
},
{
"type":"lineitem",
"name":payload[index].name,
"code":"",
"status":""
}]

Idea is to basically split every row into header and line item. and remove duplicate headers in the next step after ordering the line items. All of this is working except alternative rows are missing in the next step(verified by using index to mark rows).

I am also struggling with removal of an array field. For example payload - "status" does not work.

IF anyone can suggest a simpler approach or help me understand why alternative rows are missing, it would be great.

2
What is the expected output? What is the actual output you got? Just saying it is not the expected one is not very useful. Please share what you got. What is the input actually, an excel table? if you provide an equivalent input in JSON or XML it would be easier to reproduce and try to understand the issue?aled
As well on what basis, would you want to introduce the header - Once after every couple of rows? What are the variations possible with the input?Salim Khan
Dear @aled and Salim, thanks for the response. in my question i have added the expected input and output as a link. In context of the example, all records with same status and code should be grouped. and a header to be generated which will hold the two values. As for the current output : a lot many rows are missing. for example if i am getting a java/json array of 20 items, only 10 rows are getting printed in the csv. alternate rows are getting missed (maybe because the way i implemented is wrong). if you still need i will share the real time data - its a bit complicated though. thanks :)Vineetz

2 Answers

1
votes

Try with this

Input:

name,code,status
a,yes,active
b,yes,active
c,no,inactive
d,no,inactive
e,yes,inactive
f,yes,inactive
g,no,active
h,no,active
i,no,inactive
j,no,inactive
k,yes,active
l,yes,active

Script

%dw 2.0
output application/csv
var headerGroups = (payload groupBy (item, index) -> (item.status ++ "_" ++ item.code)) mapObject 
($$): {
    "type":"header",
    "name":"",
    "code":$[0].code,
    "status":$[0].status
}

var nameHeaderGroups= (payload groupBy (item, index) -> (item.status ++ "_" ++ item.code)) mapObject 
($$): {
    "name":[$.name]
}

fun buildNameObject(nameArray) = nameArray map 
   {
    "temp": ($ map {
    "type":"lineItem",
    "name": $ ,
    "code":"",
    "status":""
    } 
   )}
    
---
flatten(nameHeaderGroups mapObject {
    a: {(headerGroups[$$])},
    b: {(buildNameObject($.name))}.temp
}pluck ($)
)

Output:

type,name,code,status
header,,yes,active
lineItem,a,,
lineItem,b,,
lineItem,k,,
lineItem,l,,
header,,no,inactive
lineItem,c,,
lineItem,d,,
lineItem,i,,
lineItem,j,,
header,,yes,inactive
lineItem,e,,
lineItem,f,,
header,,no,active
lineItem,g,,
lineItem,h,,

This should help you get to your goal. It does arrange the lineitems with the grouping done on the basis of status and code combination. If order is of importance you can add that as well.

0
votes

Assuming that there would be two rows each of similar status and code with names being different, maybe the solution below can get you to what you need.

Input:

name,code,status
a,yes,active
b,yes,active
c,no,inactive
d,no,inactive
e,yes,inactive
f,yes,inactive
g,no,active
h,no,active
i,no,inactive
j,no,inactive
k,yes,active
l,yes,active

Script:

%dw 2.0
output application/csv headerLineNumber=0
var headerCalc = (payload groupBy (item, index) -> (item.name ++ "_" ++ item.status ++ "_" ++ item.code)) mapObject 
($$):{
    "type":"header",
    "name":$.name,
    "code":$[0].code,
    "status":$[0].status
}
---
flatten(payload map ((item,index) ->  
if((headerCalc[item.name ++ "_" ++ item.status ++ "_" ++ item.code].name contains item.name) and (isEven(index) or (index == 0)))
[{
    "type":"header",
    "name":"",
    "code":headerCalc[item.name ++ "_" ++ item.status ++ "_" ++ item.code].code,
    "status":headerCalc[item.name ++ "_" ++  item.status ++ "_" ++ item.code].status
}] ++
[{    
    "type":"lineitem",
    "name":payload[index].name,
    "code":"",
    "status":""
}]
else
    [{ 
    "type":"lineitem",
    "name":payload[index].name,
    "code":"",
    "status":""
}]))

Output:

type,name,code,status
header,,yes,active
lineitem,a,,
lineitem,b,,
header,,no,inactive
lineitem,c,,
lineitem,d,,
header,,yes,inactive
lineitem,e,,
lineitem,f,,
header,,no,active
lineitem,g,,
lineitem,h,,
header,,no,inactive
lineitem,i,,
lineitem,j,,
header,,yes,active
lineitem,k,,
lineitem,l,,