Search code examples
filteruniquejsonata

How to filter on two values in an array of objects in Jsonata?


In the array there are 5 unique objects, but the objects have some values that are duplicated. Is there a way to filter the objects based on two of the values? In this case how would I return four objects, removing the object that has duplicated "num":"999" and "name":"thing A"? Either the first object or the fourth can be removed.

{
  "array":[
    {
      "id":"1",
      "num":"999",
      "name":"thing A"
    },
    {
      "id":"2",
      "num":"888", 
      "name":"thing A"
    },
    {
      "id":"3",
      "num":"777",
      "name":"thing B"
    },
    {
      "id":"4",
      "num":"999",
      "name":"thing A"
    },
    {
      "id":"5",
      "num":"999",
      "name":"thing B"
    }    
  ]
}

Results can be Either:

{
  "array":[    
    {
      "id":"2",
      "num":"888", 
      "name":"thing A"
    },
    {
      "id":"3",
      "num":"777",
      "name":"thing B"
    },
    {
      "id":"4",
      "num":"999",
      "name":"thing A"
    },
    {
      "id":"5",
      "num":"999",
      "name":"thing B"
    }    
  ]
}

Or:

{
  "array":[
    {
      "id":"1",
      "num":"999",
      "name":"thing A"
    },
    {
      "id":"2",
      "num":"888", 
      "name":"thing A"
    },
    {
      "id":"3",
      "num":"777",
      "name":"thing B"
    },    
    {
      "id":"5",
      "num":"999",
      "name":"thing B"
    }    
  ]
}

Solution

  • You can use the $reduce function to filter out duplicates:

    {
      "array": $reduce(array, function ($acc, $item) {(
        $alreadyExistsInAcc := $acc[num = $item.num and name = $item.name];
        $alreadyExistsInAcc ? $acc : $append($acc, $item)
      )}, [])
    }
    

    Check it out on the playground: https://stedi.link/5CNdBAZ