'Mulesoft: Find for a value in array and replace the contents based on 2nd array

1st Array - set of items with pricing and shipping information. Note:

  1. The same ItemID is having 2 ItemFinalPrices(ItemPrice and ShippingPrice).

  2. All other values in 1st array should be present in the final message.

  3. Only if ItemID is present in 2nd array their respective prices should be updated.

    [
     {
         "ItemPrice": {
             "ItemID": "1000300",
             "ItemFinalPrice": 849.98,
             "UnitOfMeasure": "EACH"
         },
         "ShippingPrice": {
             "ItemID": "1000300",
             "ItemFinalPrice": 10.0,
             "UnitOfMeasure": "EACH"
         }
     },
     {
         "ItemPrice": {
             "ItemID": "1000541",
             "ItemFinalPrice": 1849.98,
             "UnitOfMeasure": "EACH"
         },
         "ShippingPrice": {
             "ItemID": "1000541",
             "ItemFinalPrice": 90.0,
             "UnitOfMeasure": "EACH"
         }
     },
     {
         "ItemPrice": {
             "ItemID": "1000549",
             "ItemFinalPrice": 189.98,
             "UnitOfMeasure": "EACH"
         },
         "ShippingPrice": {
             "ItemID": "1000549",
             "ItemFinalPrice": 190.0,
             "UnitOfMeasure": "EACH"
         }
     }
    

    ]

My 2nd Array is a list of ItemIds with updated Pricing and Shipping amount information. This array will not have all the items., it will just have updated item details.

[
  {
    "ItemId": "1000300",
    "UpdatedItemPrice": 99.98,
    "UpdatedShippingAmount": 19.72
  },
  {
    "ItemId": "1000549",
    "UpdatedItemPrice": 199.99,
    "UpdatedShippingAmount": 14.12
  }
]

For updated items, the respective Price Info and for other Items - the old PriceInfo has to be mapped. Expected Output:

 [
    {
        "ItemPrice": {
            "ItemID": "1000300", // ItemID is present in updated array, so updated price info to be mapped
            "ItemFinalPrice": 99.98,  //Updated UpdatedItemPrice
            "UnitOfMeasure": "EACH"
        },
        "ShippingPrice": {
            "ItemID": "1000300",
            "ItemFinalPrice": 19.72, //Updated UpdatedShippingAmount
            "UnitOfMeasure": "EACH"
        }
    },
    {
        "ItemPrice": {
            "ItemID": "1000541", //Same ItemId and same price info
            "ItemFinalPrice": 1849.98,
            "UnitOfMeasure": "EACH"
        },
        "ShippingPrice": {
            "ItemID": "1000541",
            "ItemFinalPrice": 90.0,
            "UnitOfMeasure": "EACH"
        }
    },
    {
        "ItemPrice": {
            "ItemID": "1000549", //ItemID is present in updated array, so updated price info to be mapped
            "ItemFinalPrice": 199.99, //Updated UpdatedItemPrice
            "UnitOfMeasure": "EACH"
        },
        "ShippingPrice": {
            "ItemID": "1000549",
            "ItemFinalPrice": 14.12, //Updated UpdatedShippingAmount
            "UnitOfMeasure": "EACH"
        }
    }
]


Solution 1:[1]

Solution using FirstWith() and the conditional update operator. The payload is the first array.

%dw 2.0
output application/json
import * from dw::core::Arrays
var updates=[
  {
    "ItemId": "1000300",
    "UpdatedItemPrice": 99.98,
    "UpdatedShippingAmount": 19.72
  },
  {
    "ItemId": "1000549",
    "UpdatedItemPrice": 199.99,
    "UpdatedShippingAmount": 14.12
  }
]
---
payload map do {
    var thisUpdate= updates firstWith ((update, index) -> update.ItemId == $.ItemPrice.ItemID)
    ---
    $ update {
        case ItemPrice at .ItemPrice.ItemFinalPrice if (thisUpdate != null) -> thisUpdate.UpdatedItemPrice 
        case ShippingPrice at .ShippingPrice.ItemFinalPrice if (thisUpdate != null) ->  thisUpdate.UpdatedShippingAmount 
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 aled