joksnet
joksnet

Reputation: 2325

Filter by values using ./jq

Given the input of sizes:

[
  {
    "stock": 1,
    "sales": 0,
    "sizes": [
      {
        "countries": ["at", "be", "ch", "cy", "de", "ee", "es", "fi", "gr", "ie", "lu", "lv", "nl", "pl", "pt", "se", "si", "sk"],
        "size": "EU 45,5"
      },
      {
        "countries": ["it"],
        "size": "EU 45,5"
      },
      {
        "countries": ["fr"],
        "size": "EU 45,5"
      },
      {
        "countries": ["gb"],
        "size": "EU 45,5"
      }
    ]
  }
]

I will like to get the same structure without the ones that countries hasn't "de" (Germany) and remove the field complete. Expected something like this:

[
  {
    "stock": 1,
    "sizes": [
      {
        "size": "EU 45,5"
      }
    ]
  }
]

I tried this:

map(.sizes[] |= select(.countries | join(",") | contains("de"))) | map({ stock, sizes })

But the filter is not working properly, throwing jq: error (at <stdin>:48): Cannot iterate over null (null).

Tried has, in, contains, inside and nothing seems to work.

Also, how can I filter which field appears? With map({ stock, sizes }) countries still there. Can I do something like map({ stock, sizes: { size } })?

Upvotes: 0

Views: 414

Answers (1)

peak
peak

Reputation: 116640

Here's a one-liner that answers your main question -- if you can't see how it works, try breaking it up into separate pieces:

map( .sizes |= map( select(.countries | index("de") ) | del(.countries) ))

Regarding the selection of fields, you can use del/1 as above, or sometimes simply using an expression such as {key1, key2} will do the trick. Consider also this function and the following example:

def query(queryobject):
  with_entries( select( .key as $key | queryobject | has( $key ) ));

Example:

$ jq -c -n '{"a": 1, "b": null, "c":3} | query( {a,b,d} )'
{"a":1,"b":null}

Upvotes: 1

Related Questions