Search code examples
arraysfunctiondataweavemule4

In array of objects with similar division, check the new record and previous record and aggregate the response in dataweave


Input:

[
  {
    "employeeId": 100,
    "firstName": "John",
    "lastName": "Chen",
    "division": "2024-DOA09-1111",
    "email": "[email protected]",
    "freshHire": false,
    "position": "M"
  },
  {
    "employeeId": 101,
    "firstName": "Ameya",
    "lastName": "Job",
    "division": "2024-DOA09-1111",
    "email": "[email protected]",
    "freshHire": false,
    "position": "M"
  },
  {
    "employeeId": 102,
    "firstName": "Pat",
    "lastName": "Fay",
    "division": "2024-DOA09-1111",
    "email": "[email protected]",
    "freshHire": false,
    "position": "M"
  }
]

dataweave code:

%dw 2.0
fun combine(val,old, new) = (if(if(val) true else (if((new.position == 'C') and !(isEmpty(new.employeeId)) ) true else false)) true else (if((old.position == 'D') and !(isEmpty(old.employeeId)) ) true else false))
output application/json
---
(payload map ((item, index) -> if(sizeOf(payload) == 2) (combine(payload[index].freshHire,payload[index], payload[index+1])) else (combine((combine(payload[index].freshHire,payload[index], payload[index+1])), payload[index+1], payload[index+2]))))[0]

expected output: false

Condition for the dataweave is as follows.

Boolean value = if(oldfreshHire == true) true else (if((newPosition == "M") and !isEmpty(newemployeeId)) true else false)
value1= if(value == true) true else (if((oldPosition == "M") and !isEmpty(oldemployeeId)) true else false)

oldPosition=Position value in index 0, newPosition=Position value in index 1, this continue for all indexes next oldPosition will be the response of 1st and 2nd record and newPosition will be 3rd record and so on.. old and new prefix is same for all fields mentioned. Here value variable is first determined and then that value is again used for value1 evaluation. value1 variable will be the final output which is expected. Here Input has 3 records so based on the condition, 1st and 2nd record with employeeId 100 and 101 are passed to the condition as old and new respectively. oldfreshHire=false from 1st record, newPosition=M and newemployeeId=101 from 2nd record, so value=false. then oldPosition=M and oldemployeeId=100 so value1=false. then we will consider previous result as old and 3rd record as new so oldfreshHire=false(value1 result), newPosition=M and newemployeeId=102 from 3rd record so value=false as per condition. then oldPosition=M and oldemployeeId=101 from 2nd record so it will consider (index-1) as old for position and employeeId and value1=false as final result.

I am getting the required output for the given input but if there are more then this might not work. also I wanted to check if this code is correct or we can update it to alternate one. Please let me know if this can be updated.


Solution

  • I don't fully understand the logic but what the script is doing is applying the combine() function to each element and the next one. That can also be done using the reduce() built-in function.

    Also combine() is overcomplicated. If you are going to return true or false depending on a condition just return the condition. It doesn't needs a separate argument if the value is also part of another argument.

    This seems to return the same result, but as I said it is not fully clear what is intended.

    %dw 2.0
    output application/json  
    
    fun combine(val, old, new) =
        if ((val) or        
                ((new.position == 'C') and !(isEmpty(new.employeeId))))
            true
        else ((old.position == 'D') and !(isEmpty(old.employeeId)))
    ---
    (payload reduce ((item, accumulator={old:{}, previous:null }) 
        -> {old: item, previous: combine(accumulator.previous default item.freshHire, accumulator.old, item)})).previous
    

    Output:

    false