Search code examples
muledataweavemulesoft

How to filter an array of objects when object key contains specific values


I have an array of objects which contains orderId & productId. If order contains 2 specific productIds then we need to remove those objects, but only when both productIds present. Either one of the productId is not present then don't need to remove those objects.

  • when the product Id's 454.110600 & 891.010000 match on the same order, delete both
  • when the product Id's 824.010000 & 890.010000 match on the same order, delete both

Input:

`[
  {
    "orderId": 1,
    "productId": "454.110600"
  },
  {
    "orderId": 1,
    "productId": "891.010000"   
  },
  {
    "orderId": 1,
    "productId": "103.110603" 
  },
  {
    "orderId": 2,
    "productId": "890.010000"
  },
  {
    "orderId": 2,
    "productId": "824.010000"   
  },
  {
    "orderId": 2,  
    "productId": "123.110601"  
  },
{
    "orderId": 3,  
    "productId": "454.110600"  
  }]`

Expected Output:

`  [  
  {
    "orderId": 1,
    "productId": "103.110603" 
  },  
  {
    "orderId": 2,  
    "productId": "123.110601"  
  },
{
    "orderId": 3,  
    "productId": "454.110600"  
  }]
`

I tried below dataweave, but not giving expected output

%dw 2.0 var product = [ {"productId" : "454.110600"}, {"productId" : "891.010000"}, {"productId" : "824.010000"}, {"productId" : "892.010000"} ]

output application/json

---

((payload groupBy ((item, index) -> item."orderId")) pluck ((value, key, index) -> value)) map (items) -> items filter (not (product contains {"productId": $."productId"}))


Solution

  • Not sure if the logic is correct but I understood it as remove the products from the order if the there are more than two products found in a list of products that needs to be removed. You can try below:

    %dw 2.0
    output application/json
    
    var productIdsToRemove = ["454.110600", "891.010000", "824.010000", "890.010000"]
    
    var groupedData = payload groupBy ((item, index) -> item.orderId)
    
    fun filterData(orderId) = do {
        var commonItems = groupedData[orderId].productId filter (productIdsToRemove contains $)
        ---
        if (sizeOf(commonItems) >= 2) groupedData[orderId] filter !(productIdsToRemove contains $.productId)
        else groupedData[orderId]
    }
    ---
    keysOf(groupedData) flatMap ((item, index) -> filterData(item))
    

    This results to:

    [
      {
        "orderId": 1,
        "productId": "103.110603"
      },
      {
        "orderId": 2,
        "productId": "123.110601"
      },
      {
        "orderId": 3,
        "productId": "454.110600"
      }
    ]