Search code examples
jsonata

Jsonata render attributes based on conditional expression


I'm wondering if it's possible to do the following in Jsonata and how it would be done:

I'm trying to render an attribute based on a boolean expression. I have this JSON,

  "listToExclude": [2],
  "objs":[
    {
      "id": 1,
      "name":"name1"
    },
    {
      "id": 2,
      "name":"name2"
    }
 ] 
}

and this is the desired JSON output,

{
  "objs": [
    {
      "id": 1,
      "name": "name1"
    },
    {
      "id": 2
    }
  ]
}

As you can see, the 2nd object does not have the attribute name.

I tried this approach but it didn't work,

{
    "objs": ($.objs ~>|$|{
        "name": name[$not(id in $$.listToExlude)]
    }|;)
}

Any ideas?


Solution

  • I was able to do it, although it required some creative thinking. Here's how I did it:

    1. Filter out the attibute from the objects (in this case, name), and store the result in a variable ($objs1);
    2. store in another variable ($objs2) all the objects in the array whose ids are not in the list listToExclude;
    3. Merge both objects by id ($objs3). This way, we have an array of objects, where we filtered out all the attributes defined in $objs1, only in the objects whose ids match the ones defined in listToExclude.
    (
        $objs1 :=  ($.objs ~>|$|{},["name"]|;);
    
        $objs2 := $filter ($.objs, function($el){
           $not($el.id in $$.listToExclude)
        });
    
        $objs3 := ($$ ~> | $objs1 | ($id := id; $objs2[$id = $.id]),[]|)
    
        {
            "obj": $objs1
        }
    )
    

    This solution outputs the desired outcome. Here's a link with the working solution: https://try.jsonata.org/d31UAmyWc