Получить элемент после / перед соответствующим в json с помощью jq - PullRequest
0 голосов
/ 29 апреля 2019

Предположим, у меня есть следующий вход json для команды jq:

[
  {"type":"dog",  "set":"foo"},
  {"type":"bird", "set":"bar"},
  {"type":"cat",  "set":"blaz"},
  {"type":"fish", "set":"mor"}
]

Я знаю, что в этом массиве есть элемент, для которого type является «птицей», в данном случае вторым элементом. Но я хочу, чтобы его следующий (или предыдущий) брат, то есть элемент после (до) него, в данном случае третий (первый) элемент. Как я могу получить его в JQ?

Кроме того, у меня есть еще один вопрос: если соответствующий элемент (то есть элемент, значение которого type, которое я знаю) является последним в массиве, я хочу, чтобы он получал первый как следующий (то есть , цикл через массив) вместо того, чтобы ничего не возвращать. То же самое, является ли соответствующий элемент первым (тогда я хочу получить последний элемент).

Ответы [ 2 ]

1 голос
/ 29 апреля 2019

позвольте мне также предложить вам альтернативное решение, основанное на Unix-инструменте Walk-Path для JSON: jtc - там вы «кодируете» логику запроса прямо в путь:

например. найти запись "type":"bird", а затем предшествующий элемент (в массиве родителя) будет выглядеть так:

bash $ <file.json jtc -w'[type]:<bird> [-1]<idx>k [-1]>idx<t-1' -r
{ "set": "foo", "type": "dog" }

позвольте мне разобрать это для вас:

  • [type]:<bird> - рекурсивно найдет запись "type":"bird"
  • [-1]<idx>k - поднимется на 1 уровень в дереве JSON (выберите родителя, эффективно выделите всю запись {"type":"bird", "set":"bar"}) и запомнит его индекс массива в пространство имен idx
  • [-1]>idx<t-1 - снова поднимется на 1 уровень в JSON (выбор верхнего массива) и будет искать (не рекурсивно) запись с индексом (сохраненным в idx) со смещением на -1

Одинаково один раз может выбрать следующего брата:

bash $ <file.json jtc -w'[type]:<bird>[-1]<idx>k[-1]>idx<t1'
{ "set": "blaz", "type": "cat" }

Или выберите первую запись (на основе последнего совпадения):

bash $ <file.json jtc -w'[type]:<fish>[-1]<idx>k[-1]>idx<t-1000' -r
{ "set": "foo", "type": "dog" }

(просто укажите какое-то определенно низкое значение в качестве относительного квантификатора - оно нормализуется к первой записи)

PS> Раскрытие информации: я создатель jtc инструмента

1 голос
/ 29 апреля 2019

Ради определенности, давайте предположим, что вы хотите извлечь тройку (before, focus, after) в виде массива, где before и after оборачиваются, как описано. Для простоты предположим также, что исходный массив имеет длину не менее 2.

Далее, для простоты изложения и понимания, мы определим вспомогательную функцию для извлечения трех элементов:

# $i is assumed to be a valid index into the input array,
# which is assumed to be of length at least 2
def triple($i):
  if $i == 0 then [last] + .[0:2]
  elif $i == (length-1) then .[$i-1: $i+2] + [first]
  else .[$i-1: $i+2]
  end;

Теперь нам осталось только найти индекс и использовать его:

(map(.type) | index("bird")) as $i
| if $i then triple($i) else empty end

Используя этот подход, можно легко получить другие варианты.

...