Search code examples
jsonata

How to make JSONata for getting results like


If I have a source like

{
    "Data": {
        "CREATED": "2022-04-08",
        "EDITED": "2023-04-08"
    }
}

I want to get an output like

{
    "Date" : {
      "Created" : "2022-04-08"
    },

    "Date" : {
      "Updated" : "2023-04-08"
    }
}

If the source doesn't have value with "CREATED" like

{
    "Data": {
        "EDITED": "2023-04-08"
    }
}

I want to get an output like

{
    "Date" : {
      "Updated" : "2023-04-08"
    }
  
}

Can anyone please help me how to make JSONata for getting output as above?


Solution

  • Be carefull you cannot have two prop "Date" in a json at the same level!
    Having said that, you could try to check each key like:

    (
        $checkDate := function($k, $v){
            $type($v) = 'object' ?
                $each($v, function($vv, $kk) {(
                    $kk = "CREATED" ? {"Created": $vv} :
                    $kk = "EDITED" ? {"Updates": $vv}
                )})  ~> $merge()
            : $v
        };
    
        $each(function($value, $key) {
            { $key:  $checkDate( $key, $value) }
        })  ~> $merge()
    )
    

    The last 'each' will pass every key-value in your first level to the 'checkDate' function. That will override eventually "CREATED" or "EDITED" field in Data props.

    Note: 'Each' will pass an object as array but 'merge' will revert that, at the end of the process. So don't worry about '~> $merge()' at the and of 'each' functions.

    OR

    If you need to override few fields, you can just apply a transformation like:

    $ ~> |Data|{'Created': CREATED, 'Updated': EDITED}, ['CREATED', 'EDITED']|
    

    This will:

    1. locate 'Data'
    2. add there 'Created' and 'Updated' fields
    3. delete old 'CREATED', 'EDITED' keys
    4. give you back the updated object