Home > OS >  How to get value by comparing it with index of another field in the array of objects
How to get value by comparing it with index of another field in the array of objects

Time:07-01

If the text we are looking for is "PQR" then we should get the corresponding subfield value "dataweave". In the first object, we have the value but in the second object that is missing so it should give default null. Also the text will not be in order. "ABC","BCD","PQR" are static in output even though it might come or not come in the input.

Input:

 [ {
            "data":{
            "field": "value"
            },
            "field1": "ABC",
            "subfield01": "test",
            "field2": "BCD",
            "subfield02": "mule",
            "field3": "PQR",
            "subfield3": "dataweave"
            .
            .
            .
            "field10":"",
            "subfield10": ""
    },
    {
            "data":{
            "field": "value"
            }
            "field1": "BCD",
            "subfield01": "testing",
            "field2": "ABC",
            "subfield02": "mulesoft",
            "field3": "",
            "subfield03": ""
            .
            .
            .
            "field10":"",
            "subfield10": ""
    }
    ]

Expected Output:

[
  {
    "SearchFieldABC": "test",
    "SearchFieldBCD": "mule",
    "SearchFieldPQR": "dataweave",
    "fields123": "value", 
    "fields678": "value2"
  },
  {
    "SearchFieldABC": "mulesoft",
    "SearchFieldBCD": "testing",
    "SearchFieldPQR": null,
    "fields123": "value", 
    "fields678": "value2"
  }
]

CodePudding user response:

Though previous answer looks ok I post my

%dw 2.0
output application/json
var query = ["ABC", "BCD", "PQR"]
---
payload map ((item, index) -> do { //Group by index
    var fieldByIndex = item 
        groupBy ((value, key) -> do {
            key as String match  {
                case f if(f startsWith "field") -> f[5 to -1]
                case f if(f startsWith "subfield") -> f[8 to -1]
            }
        })
     ---
     {
        (
            query 
                map ((q, index) -> do {
                    var fieldSubField = (fieldByIndex 
                                            filterObject ((value, key, index) -> value['field$(key)'] == q))[0] 
                                                            
                    ---
                    {
                        "SearchField$(q)": valuesOf(
                                                    fieldSubField 
                                                            filterObject ((value, key, index) -> key as String startsWith "subfield"))[0]  
                    }
                })
        )  
     }
} ) 

CodePudding user response:

You can use the following dataweave. I have divided it into two main functions, first mapFieldsToSubFields takes an element from your input and basically generates an object that directly maps the field's values to their respective subfield's value. So it will generate the following output for example

{
  "ABC": "test",
  "BCD": "mule",
  "PQR": "dataweave"
}

This will make it is easier for the next function mapToRequiredOutput to quickly map it to required format and insert the missing fields from the input.

%dw 2.0
output application/json

var allFields = payload flatMap entriesOf($)
                    filter ($.key startsWith "field") and (!isEmpty($.value))
                    map $.value
                    distinctBy $

fun mapFieldsToSubFields(object) = 
    object filterObject ((value, key) -> (key startsWith "field")) // Remove all "subfields"
            filterObject !isEmpty($) // Remove empty field values
            mapObject ($): object["sub$($$)"] // example: $ = "ABC" and $$ = field1, so object["sub$($$)"] = object[subfield1] = "test"

fun mapToRequiredOutput(object) = {(
        allFields map {"SearchField$($)": object[$]}
    )}
---
payload 
    map mapFieldsToSubFields($)
    map mapToRequiredOutput($)
  • Related