Возвращение к 1 документу после `.[]` в yq

Дело 1

С вводом

- groupx:
- groupy:

Выражение yq length равно 2

Случай 2

С вводом

groupx:
groupy:

Выражение yq length также равно 2

Случай 3 – использование знака (.[]) для преобразования случая 1 в вариант 2.

Сначала мы преобразуем входные данные случая 1 в случай 2, выполнив:

$ yq '.[]' case1.yaml

groupx:
groupy:

Обратите внимание, что это тот же результат, что и case2.yaml

Если я захочу расширить это выражение выражением case2, я не получу тот же результат, вместо этого я получу следующее:

$ yq '.[] | length' case1.yaml
1
1

Если я добавлю второй процесс yq, я получу тот же результат, что и в случае 2:

$ yq '.[]' case1.yaml | yq 'length'
2

Вопрос

Почему оператор splat yq фактически превращает результат в несколько документов yaml? Это не имеет смысла, поскольку тот же вывод, который снова подается в качестве входных данных в yq, не приводит к созданию нескольких документов.

Если это запланированное поведение, можете ли вы вернуться к одному документу после использования .[], не запуская новый процесс yq?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Случай 1 — это один документ с seq (массивом), который содержит две карты (объекты), каждая из которых имеет ровно один ключ (поле).

Случай 2 — один документ с картой (объектом), содержащей два ключа (поля).

Применение .[] в любом случае деструктурирует тип верхнего уровня документа (seq в первом случае, карту во втором) и приводит (в обоих случаях) к двум документам (первый имеет две карты, второй - две (null) ценности).

Таким образом, применение length к этому результату в одном и том же фильтре всегда дает два числа (оба 1 в первом случае, поскольку у вас есть две карты, содержащие по одному ключу каждая, и оба 0 во втором, поскольку у вас есть два скалярных значения, которые ничего не содержат). .

Однако применение length к этому результату в другом фильтре приводит к переоценке входных данных. Теперь, в первом случае, две карты с одним элементом сворачиваются в одну, содержащую два элемента, отсюда и общий результат 2. Во втором случае скалярные значения не могут быть свернуты дальше, поэтому результаты остаются прежними (два числа, оба 0).

Я не могу говорить за разработчика, задумано это или нет. Но я могу утверждать, что это отклонение применимо только к mikefarah/yq , а не к kislyuk/yq, который продолжает обрабатывать входные данные как два документа, поскольку активно печатает разделитель документов. (Хотя в mikefarah/yq есть опция --no-doc (или -N), позволяющая «не печатать разделители документов», но, похоже, она применяется по умолчанию — проверено с версиями v4.34.2 и v4.40.5).

Если это запланированное поведение, можете ли вы вернуться к одному документу после использования .[], не запуская новый процесс yq?

Конечно. Собрать предметы после деструктуризации в один предмет можно, но его реализация зависит от того, какой тип он должен иметь.

Если вы хотите, чтобы это была последовательность результирующих документов, заключите фильтр в скобки, чтобы собрать в него элементы. Таким образом, .[] | … | length станет [.[] | …] | length и должно уступить 2. На самом деле, вы можете сократить [.[] | …], используя map(…).

Если вы хотите, чтобы это была карта (так же, как она сворачивается при двух вызовах), вы можете использовать ireduce для итеративного добавления всех элементов к изначально пустой карте: (.[] | …) as $i ireduce ({}; . + $i) | length. (Примечание: с помощью kislyuk/yq у вас есть фильтр add, который может свернуть последовательность карт в одну.)

В этот момент я просто радуюсь, что сломана не моя ментальная модель. Действительно, map() кажется более очевидным оператором/функцией для использования. Может быть, в прошлом я поспешно дошел до .[]

hbogert 17.04.2024 14:26

Другие вопросы по теме

Похожие вопросы