1

In my case, I have one array of object that needs to be split based on "L1" occurrence. For example, the below JSON request has multiple L1.

[
  {
    "route": "F1",
    "Company Code": "One Total Item Count"
  },
  {
    "route": "D1",
    "Company Code": "Two Total PO Amount"
  },
  {
    "route": "L1",
    "Company Code": "Three Total Item Count"
  },
  {
    "route": "F1",
    "Company Code": "One Total PO Amount"
  },
  {
    "route": "D1",
    "Company Code": "Two Total Item Count"
  },
  {
    "route": "L1",
    "Company Code": "Three Total Item Count"
  },
  {
    "route": "D1",
    "Company Code": "Two Total Item Count"
  },
  {
    "route": "L1",
    "Company Code": "Three Total Item Count"
  }
]

I'm trying to split based on L1, and expecting the response like below.

[
  [
    {
      "route": "F1",
      "Company Code": "One Total Item Count"
    },
    {
      "route": "D1",
      "Company Code": "Two Total PO Amount"
    },
    {
      "route": "L1",
      "Company Code": "Three Total Item Count"
    }
  ],
  [
    {
      "route": "F1",
      "Company Code": "One Total PO Amount"
    },
    {
      "route": "D1",
      "Company Code": "Two Total Item Count"
    },
    {
      "route": "L1",
      "Company Code": "Three Total Item Count"
    }
  ],
  [
    {
      "route": "D1",
      "Company Code": "Two Total Item Count"
    },
    {
      "route": "L1",
      "Company Code": "Three Total Item Count"
    }
  ]
]

In dataweave I tried spiltAt, filter, and other functions to split by separate sets based on L1 occurrence. but its not working the way I'm expecting.

Expert, please help me solve this logic.

Thanks in advance.

2 Answers 2

2

This can be resolved using a recursive function to split at the first time "L1" appears (splitAt((a indexWhere (item) -> item.route == value) + 1)) then recursively apply the same logic to the rest of the array. We need to be careful of the conditions to finish the recursion to avoid infinite recursion or getting empty arrays.

The question doesn't clarify if the last element has the "L1" value always. This script should also work if not.

For a bit extra re usability I made the condition to be a closure. Since my function has two arguments it can be used with in-fix notation in DataWeave, like splitAt().

%dw 2.0
output application/json
import * from dw::core::Arrays

fun splitAfter(a, condition)= do {
    var splitted = a splitAt((a indexWhere condition($)) + 1) 
    ---
    if (sizeOf(a) > 1 and !isEmpty(splitted.l))
        [splitted.l] ++ splitAfter(splitted.r, condition)
    else
        a
}
---
payload splitAfter (item) -> item.route == "L1"
Sign up to request clarification or add additional context in comments.

Comments

1

Another approach with slice which splits array based on index numbers

Here idx contains index numbers where route = "L1" ,In above example it is [2,5,7]

slice(0,(2+1)) // 0 to index(0)+1

slice((2+1),(5+1)) // index (1)+1 to index (2)+1 and so on

slice((5+1),(6+1)) //index (n-1)+1 to index (n)+1

This will also work if L1 is in first position or last position of array

%dw 2.0
output application/json
import * from dw::core::Arrays

var idx=payload flatMap((if($.route == "L1")$$ else []))
---
(idx map(
        (
            if($$==0)
                slice(payload,0,(idx[0]+1))
            else if(($$+1) == sizeOf(idx))
                slice(payload,(idx[-2]+1), (idx[-1]+1))
            else slice(payload,idx[$$-1]+1,idx[$$]+1)
        )
))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.