OverlordQ
OverlordQ

Reputation: 167

Filter objects using multiple conditions including comparing two object fields

Have a list of JSON object and am trying to filter them based on minimum value check and a comparison between two of its fields.

{
  "preview": false,
  "init_offset": 0,
  "messages": [],
  "fields": [
    {
      "name": "A"
    },
    {
      "name": "B"
    },
    {
      "name": "Diff"
    },
    {
      "name": "Threshold"
    }
  ],
  "results": [
    {
      "A": "foo",
      "B": "bar",
      "Diff": "1095",
      "Threshold": "1200"
    },
    {
      "A": "baz",
      "B": "bux",
      "Diff": "81793",
      "Threshold": "0"
    },
    {
      "A": "quux",
      "B": "quuz",
      "Diff": "194"
    },
    {
      "A": "moo",
      "B": "goo",
      "Diff": "5000",
      "Threshold": "2000"
    }
 ]
}

Closest I've come to is

.results
| map(.Threshold //= "0")
| .[]
| select((.Threshold|tonumber > 0) and 
         (.Diff|tonumber > .Threshold|tonumber))

But that gives a

Cannot index string with string "Threshold"

error.

Basically I want to return all results where Diff is greater than a non-zero Threshold. So in this case:

{
  "A": "moo",
  "B": "goo",
  "Diff": "5000",
  "Threshold": "2000"
}

Using jq 1.5 FWIW.

Upvotes: 0

Views: 307

Answers (1)

peak
peak

Reputation: 116870

You're just missing some parentheses. Compare:

select((.Threshold|tonumber) > 0 and
       (.Diff|tonumber) > (.Threshold|tonumber))

Or avoiding the double-conversion:

select( (.Threshold|tonumber) as $t
        | $t > 0 and (.Diff|tonumber) > $t )

You could also simplify the entire program a bit:

.results[]
| select( ((.Threshold // 0) | tonumber) as $t 
          | $t > 0 and (.Diff|tonumber) > $t )

Upvotes: 1

Related Questions