Search code examples
arraysmuledataweavemulesoft

how to map multiple array elements in mulesoft


we have to map multiple array objects to form the resultant array.

Input:

{
    "data": {
    "contents": {
    "desserts": [
    {
        "id": "0001",
        "type": "donut",
        "name": "Cake",
        "ppu": 0.55,
        "batters":
            
                    [
                        { "id": "1001", "type": "Regular" },
                        { "id": "1002", "type": "Chocolate" }
                    ],
        "topping":
            [
                
            ],
        "base": [
            {
                "id": "001",
                "type": "wheat"
            },
            {
                "id": "003",
                "type": "corn"
            }
        ]
    },
    {
        "id": "0002",
        "type": "donut",
        "name": "Raised",
        "ppu": 0.55,
        "batters":
            [
                        { "id": "1004", "type": "Devil's Food" }
                    ],
        "topping":
            [
                { "id": "5001", "type": "None" },
                { "id": "5002", "type": "Glazed" }
            ],
        "base": [
            {
                "id": "005",
                "type": "cashew"
            }
        ]
    }
]
}
}
}

Expected output:

[
  {
    "id": "0001",
    "type": "donut",
    "name": "Cake",
    "ppu": 0.55,
    "batterid": "1001",
    "battertype": "Regular",
    "toppingid": "",
    "toppingtype": "",
    "baseid": "001",
    "basetype": "wheat"
  },
  {
    "id": "0001",
    "type": "donut",
    "name": "Cake",
    "ppu": 0.55,
    "batterid": "1002",
    "battertype": "Chocolate",
    "toppingid": "",
    "toppingtype": "",
    "baseid": "001",
    "basetype": "wheat"
  },
  {
    "id": "0001",
    "type": "donut",
    "name": "Cake",
    "ppu": 0.55,
    "batterid": "1001",
    "battertype": "Regular",
    "toppingid": "",
    "toppingtype": "",
    "baseid": "003",
    "basetype": "corn"
  },
  {
    "id": "0001",
    "type": "donut",
    "name": "Cake",
    "ppu": 0.55,
    "batterid": "1002",
    "battertype": "Chocolate",
    "toppingid": "",
    "toppingtype": "",
    "baseid": "003",
    "basetype": "corn"
  },
  {
    "id": "0002",
    "type": "donut",
    "name": "Raised",
    "ppu": 0.55,
    "batterid": "1004",
    "battertype": "Devil's Food",
    "toppingid": "5001",
    "toppingtype": "None",
    "baseid": "005",
    "basetype": "cashew"
  },
  {
    "id": "0002",
    "type": "donut",
    "name": "Raised",
    "ppu": 0.55,
    "batterid": "1004",
    "battertype": "Devil's Food",
    "toppingid": "5002",
    "toppingtype": "Glazed",
    "baseid": "005",
    "basetype": "cashew"
  }
]

Above input payload is to be mapped by taking batters, topping and base array. Object in the array is repeated for each of the batters object and topping object and base object. If any of them is null then other array should be displayed in the output. If we use reduce it is not considering the whole output object if that array is empty.

I tried to use map for desserts and then reduce for batters and map again for topping but that is not giving expected result. Also another map function needs to be added for base. so it didn't work.


Solution

  • I find that the complexity of this issue is all the renamings of keys needed. Perhaps there is an easiest solution for that. To obtain the combinations is a simple matter of implementing array multiplication with nested maps.

    %dw 2.0
    output application/json
    
    fun multiply(dessert, name1, a1, name2, a2)=
    do {
        var b1=if (isEmpty(a1)) [{ (name1++"id"):"", (name1++"type"):""}] else (a1 map ($ mapObject (name1++ $$ as String): $))
        var b2=if (isEmpty(a2)) [{ (name2++"id"):"", (name2++"type"):""}] else (a2 map ($ mapObject (name2++ $$ as String): $)) 
        ---
        b1 flatMap ((item, index) -> b2 map (($ ++ item) update {
                case id at .id! -> dessert.id
                case t at ."type"! -> dessert."type"
                case name at .name! -> dessert.name
                case ppu at .ppu! -> dessert.ppu
            })  
        ) 
    }
    ---
    payload.data.contents.desserts flatMap 
        multiply($, "", multiply($, "batter", $.batters, "base", $.base), "topping", $.topping)
    
    

    Output:

    [
      {
        "toppingid": "",
        "toppingtype": "",
        "baseid": "001",
        "basetype": "wheat",
        "batterid": "1001",
        "battertype": "Regular",
        "id": "0001",
        "type": "donut",
        "name": "Cake",
        "ppu": 0.55
      },
      {
        "toppingid": "",
        "toppingtype": "",
        "baseid": "003",
        "basetype": "corn",
        "batterid": "1001",
        "battertype": "Regular",
        "id": "0001",
        "type": "donut",
        "name": "Cake",
        "ppu": 0.55
      },
      {
        "toppingid": "",
        "toppingtype": "",
        "baseid": "001",
        "basetype": "wheat",
        "batterid": "1002",
        "battertype": "Chocolate",
        "id": "0001",
        "type": "donut",
        "name": "Cake",
        "ppu": 0.55
      },
      {
        "toppingid": "",
        "toppingtype": "",
        "baseid": "003",
        "basetype": "corn",
        "batterid": "1002",
        "battertype": "Chocolate",
        "id": "0001",
        "type": "donut",
        "name": "Cake",
        "ppu": 0.55
      },
      {
        "toppingid": "5001",
        "toppingtype": "None",
        "baseid": "005",
        "basetype": "cashew",
        "batterid": "1004",
        "battertype": "Devil's Food",
        "id": "0002",
        "type": "donut",
        "name": "Raised",
        "ppu": 0.55
      },
      {
        "toppingid": "5002",
        "toppingtype": "Glazed",
        "baseid": "005",
        "basetype": "cashew",
        "batterid": "1004",
        "battertype": "Devil's Food",
        "id": "0002",
        "type": "donut",
        "name": "Raised",
        "ppu": 0.55
      }
    ]