JQ: выберите объекты со значением ключа в наборе значений

У меня есть массив объектов json, и я хотел бы извлечь подмножество массива, чтобы поле .name соответствовало набору входных строк.

например, я хотел бы выполнить следующее.

jq -n '["a","b","c","d","e"] | map({name:.,foo:"bar"})' \
  | jq 'map(select(.name=="a" or .name=="c"))'

Я придумал следующее решение, но мое использование [...] и add похоже на то, что я упускаю что-то умное.

jq -n '["a","b","c","d","e"] | map({name:.,foo:"bar"})' \
  | jq --arg name 'a c' '
      [
        ( $name | split(" ") )[] as $name
        | map( select( .name == $name ) )
        | add
      ]'

Кроме того, это решение заставляет меня перебирать входной массив несколько раз вместо одного прохода. Любые другие идеи, как я мог решить это?


jq
person Jon    schedule 15.04.2015    source источник


Ответы (2)


Переместите все в состояние select. Вам не нужно делать два отдельных вызова jq.

$ echo '["a","b","c","d","e"]' | jq --arg names 'a c'
    'map(select(. == ($names | split(" ")[])) | { name: ., foo: "bar" })'
[
  {
    "name": "a",
    "foo": "bar"
  },
  {
    "name": "c",
    "foo": "bar"
  }
]
person Jeff Mercado    schedule 15.04.2015
comment
Я использовал первый jq для создания образца ввода в массиве формата объекта, который я анализировал... Ваш ответ полностью правильный, просто индексация немного отличается. map(select(.name==($names|split(" ")[]))) - person Jon; 05.09.2015
comment
Я спрашиваю, не могли бы вы разбить элементы синтаксиса? Я не могу понять, что эта серия специальных символов в стиле perl-esqe пытается выполнить ‹3 - person ThorSummoner; 11.07.2017

По мнению ThorSummoner, вот решение менее perl-esqe, в котором используется --argjson и внутри с комментариями в отдельных строках, которые используют преимущества поведения оболочки ':

$ echo '["a","b","c","d","e"]' | jq --argjson wanted '["a","c"]' '
  .[]                          # break array into elements
| if ([.]|inside($wanted))     # if element is in wanted
  then {name: ., foo:"bar"}    # generate desired output
  else empty                   # otherwise generate nothing
  end
'
person jq170727    schedule 25.08.2017