jsonata-js / jsonata

JSONata query and transformation language - http://jsonata.org
MIT License
2.02k stars 215 forks source link

$distinct does not return an array if no or only one item matches #630

Open Stalinko opened 1 year ago

Stalinko commented 1 year ago

This is basically the same bug as with $filter: https://github.com/jsonata-js/jsonata/issues/218

Example:

My query:

$distinct(data.title)

Data:

{
  "data": [
    { "title": "A" },
    { "title": "B" },
    { "title": "C" }
  ]
}

Returns all good:

["A", "B", "C"]

Data:

{
  "data": [
    { "title": "A" }
  ]
}

Returns:

"A"

Expected:

["A"]
markmelville commented 1 year ago

It's documented that a "sequence containing a single value is considered equivalent to that value itself, and the output ... will be that value without any surrounding structure".

This behavior of jsonata is by design. You can force an array output for an expression returning one or more values by terminating the expression with square braces ($distinct(data.title[])) and for zero or more values by wrapping it in square braces ($distinct([data.title]))

Stalinko commented 1 year ago

Okay thanks @markmelville

I just wanted to let you know this behaviour is a real bug producer. Because in programming it's kinda a rule of thumb that if some function returns array then it should never return single entities.

markmelville commented 1 year ago

Don't I know it! There are many issues both closed and open where that design decision is discussed. I searched around a little but couldn't find a good quote to share as to why the designers chose to do it that way.

craigcWC3 commented 1 month ago

@map is exhibiting the same behavior.