Использование jq для удаления элементов из массива на основе значений в других местах ввода - PullRequest
1 голос
/ 13 марта 2019

Я новичок в jq и пытаюсь обернуть голову, делая несколько вещей, которые, как я думал, будут простыми.Будем весьма благодарны за любые идеи о том, как улучшить это.

Учитывая этот вход:

{
    "source": {
        "items": [
            { "id": "aaa", "name": "this" },
            { "id": "bbb", "name": "that" },
            { "id": "ccc", "name": "the other" }
        ]
    },
    "update": {
        "toRemove": [
            "aaa",
            "ccc"
        ]
    }
}

Я хочу этот результат:

{
    "items": [
        { "id": "bbb", "name": "that" }
    ]
}

Этот фильтр делает работуно переменные заставляют меня поверить, что есть более чистый путь.

. as $root | .source + { items: [.source.items[] | select(.id as $id | $root.update.toRemove | contains([$id]) | not)]}

Ссылка на игровую площадку, если интересно: https://jqplay.org/s/GpVJfbTO-Q

Ответы [ 3 ]

2 голосов
/ 13 марта 2019

Вот краткое и эффективное решение:

.update.toRemove as $rm
| .source
| .items |= map( select(.id | IN($rm[]) | not))
1 голос
/ 13 марта 2019

Немного более короткая версия, использующая inside вместо contains:

.update.toRemove as $temp |
 {items: [.source.items[] | select([.id] | inside($temp) | not)]}
0 голосов
/ 13 марта 2019

и альтернативное решение, используя jtc

bash $ <input.json jtc -w'<items>l[-1]' | jtc -w'[id]:<bbb>[-1]' -pp
{
   "items": [
      {
         "id": "bbb",
         "name": "that"
      }
   ]
}
bash $ 

первый jtc оператор печатает items полностью, второй удаляет все, кроме объекта сbbb

* ОБНОВЛЕНИЕ * последняя версия jtc теперь позволяет использовать пространства имен.Чтобы облегчить вопрос, используйте его так:

bash $ <input.json jtc -w'[update][toRemove][:]<2rm>v [^0][id]:<2rm>s[-1]' -p | jtc -w'[source]'
{
   "items": [
      {
         "id": "bbb",
         "name": "that"
      }
   ]
}
bash $ 

Пояснения:

1.[update][toRemove][:]<2rm>v - эта часть пути обхода будет проходить по каждому элементу в toRemove при сохранении каждого повторного значения в пространстве имен 2rm

2.[^0][id]:<2rm>s[-1] - сбросит путь обхода к корню ([^0]) и найдет каждую запись JSON, соответствующую той, которая хранится в 2rm, [-1] выберет родителя найденной записи (которая выбирает запись элемента * 1031)*

3. -p удалит найденные (пройденные) элементы, а затем jtc выберет source

...