JSON path condifitional index of element based on value of another field

3.9k views Asked by At

I want to select array element based on value of another object(not array part)

{
  "array": [
    {
      "id": 1
    },
    {
      "id": 2
    }
  ],
  "conditionalField": "ab"
}

I want select array element based on value of $.conditionalField. I need something like this:

$.array[($.conditionalField == "ab" ? 0 : 1)]

Does json path support this? I use Jayway JSON Path

2

There are 2 answers

0
wp78de On BEST ANSWER

Unfortunately, this cannot be done in JSONPath as of now. Generally, current implementations lack the fluency of XPath 1.0 (let alone v2.0/3+).

A (well known) trick mimicking a conditional (if-else) in a language like XPath 1.0 that does not come with such a feature is to use a technique called "Becker's method", i.e. concatenating two mutually exclusive strings, where one of two strings becomes empty depending on a condition. In (XPath) pseudo-code:

concat(
  substring('foo', 1, number(true) * string-length('foo')),
  substring('bar', 1, number(not(true)) * string-length('bar'))
)

We might be able to do this using JSON-Path in JavaScript and leveraging script eval; I think it should look like this (slit-up for better readability):

$.[?(@.conditionalField && @.dict[0].id && @.dict[1].id && @.temp.concat( 
          @.dict[0].id.substring(0, @.conditionalField==='ab' * @.dict[0].id.length()) ) 
 .concat( @.dict[1].id.substring(0, @.conditionalField==='xy' * @.dict[1].id.length()) )
   )]

but it is not working. So, as of now, there seems to be no way to mimic an if-else construct in JSON-Path directly.

A practical approach is selecting both properties separately and make the decision in your host environment:

$.[?(@.conditionalField=='ab')].dict[0].id
$.[?(@.conditionalField=='xy')].dict[1].id
0
Jack Fleeting On

Try something like this:

$.[?(@.conditionalField=="ab")].array[1].id

Output should be:

[
   2
]