Я хотел бы объединить массивы в YAML и загрузить их через рубин -
some_stuff: &some_stuff
- a
- b
- c
combined_stuff:
<<: *some_stuff
- d
- e
- f
Я хотел бы иметь объединенный массив как [a,b,c,d,e,f]
Я получаю сообщение об ошибке: не нашел ожидаемого ключа при разборе сопоставления блоков
Как объединить массивы в YAML?
list
data-structures
yaml
lfender6445
источник
источник
Ответы:
Если целью является запуск последовательности команд оболочки, вы можете добиться этого следующим образом:
Это эквивалентно:
Я использовал это на своем
gitlab-ci.yml
(чтобы ответить на комментарий @ rink.attendant.6 по вопросу).Рабочий пример, который мы используем для поддержки
requirements.txt
частных репозиториев из gitlab:где
requirements_test.txt
содержит, например,-e git+ssh://git@gitlab.com/example/example.git@v0.2.2#egg=example
источник
Обновление: 2019-07-01 14:06:12
Контекст
Этот пост предполагает следующий контекст:
Проблема
lfender6445 хочет объединить два или более списков в файле YAML, и чтобы эти объединенные списки отображались как один единственный список при синтаксическом анализе.
Решение (обходной путь)
Это может быть получено просто путем присвоения привязок YAML сопоставлениям, где желаемые списки появляются как дочерние элементы сопоставлений. Однако здесь есть предостережения (см. «Ловушки» ниже).
В приведенном ниже примере у нас есть три сопоставления (
list_one, list_two, list_three
) и три якоря и псевдонима, которые ссылаются на эти сопоставления, где это необходимо.Когда файл YAML загружается в программу, мы получаем список, который нам нужен, но может потребоваться небольшая модификация после загрузки (см. Подводные камни ниже).
пример
Исходный файл YAML
Результат после YAML.safe_load
Ловушки
Вывод
Этот подход позволяет создавать объединенные списки с помощью функции псевдонима и привязки YAML.
Хотя выходной результат представляет собой вложенный список списков, его можно легко преобразовать с помощью
flatten
метода.Смотрите также
Обновленный альтернативный подход @Anthon
Примеры
flatten
методаflatten
;; Слияние / сглаживание массива массивовflatten
;; http://ruby-doc.org/core-2.2.2/Array.html#method-i-flattenflatten
;; https://softwareengineering.stackexchange.com/a/254676/23884источник
Это не сработает:
слияние поддерживается только спецификациями YAML для сопоставлений, но не для последовательностей
вы полностью смешиваете вещи, имея ключ слияния,
<<
за которым следует разделитель ключ / значение:
и значение, которое является ссылкой, а затем продолжаете со списком на том же уровне отступаЭто не правильный YAML:
Таким образом, ваш пример синтаксиса даже не имеет смысла в качестве предложения по расширению YAML.
Если вы хотите сделать что-то вроде объединения нескольких массивов, вы можете рассмотреть такой синтаксис, как:
где
s1
,s2
,s3
являются якорями на последовательностях (не показаны) , которые вы хотите объединить в новую последовательность и затем иметьd
,e
иf
приложенные к этому. Но YAML сначала определяет глубину такого рода структур, поэтому во время обработки ключа слияния нет реального контекста. У вас нет доступного массива / списка, к которому вы могли бы прикрепить обработанное значение (закрепленную последовательность).Вы можете использовать подход, предложенный @dreftymac, но это имеет огромный недостаток, заключающийся в том, что вам нужно каким-то образом знать, какие вложенные последовательности нужно сгладить (т.е. зная «путь» от корня загруженной структуры данных до родительской последовательности), или что вы рекурсивно просматриваете загруженную структуру данных в поисках вложенных массивов / списков и без разбора сглаживаете их все.
Лучшим решением IMO было бы использовать теги для загрузки структур данных, которые выполняют сглаживание за вас. Это позволяет четко обозначать, что нужно развернуть, а что нет, и дает вам полный контроль над тем, выполняется ли это выравнивание во время загрузки или во время доступа. Какой из них выбрать, зависит от простоты реализации и эффективности использования времени и места для хранения. Это тот же компромисс, который необходимо сделать для реализации ключевой функции слияния, и не существует единого решения, которое всегда было бы лучшим.
Например, моя
ruamel.yaml
библиотека использует слияния грубой силы во время загрузки при использовании своего безопасного загрузчика, что приводит к объединению словарей, которые являются обычными dicts Python. Это слияние должно выполняться заранее и дублирует данные (неэффективное использование пространства), но при этом выполняется быстрый поиск значений. При использовании загрузчика туда и обратно вы хотите иметь возможность выгружать слияния без объединения, поэтому их нужно хранить отдельно. Такая структура данных, как dict, загруженная в результате загрузки туда и обратно, занимает мало места, но имеет более медленный доступ, поскольку ему нужно попытаться найти ключ, не найденный в самом dict при слияниях (и он не кэшируется, поэтому он нужно делать каждый раз). Конечно, такие соображения не очень важны для относительно небольших файлов конфигурации.Следующее реализует схему слияния для списков в Python с использованием объектов с тегом,
flatten
которые на лету рекурсируют в элементы, которые являются списками и помеченыtoflatten
. Используя эти два тега, вы можете получить файл YAML:(использование последовательностей стилей потока и блока совершенно произвольно и не влияет на загруженный результат).
При итерации по элементам, которые являются значением для ключа,
m1
это "рекурсивно" превращается в последовательности, помеченныеtoflatten
, но отображает другие списки (с псевдонимами или без них) как один элемент.Один из возможных способов достижения этого с помощью кода Python:
который выводит:
Как видите, вы можете видеть, что в последовательности, которая требует выравнивания, вы можете использовать псевдоним для помеченной последовательности или вы можете использовать помеченную последовательность. YAML не позволяет делать:
, т. е. пометить закрепленную последовательность, так как это существенно превратит ее в другую структуру данных.
Использование явных тегов - это IMO лучше, чем какая-то магия, как с ключами слияния YAML
<<
. Если ничего другого, вам теперь придется пройти через обручи, если у вас есть файл YAML с сопоставлением, у которого есть ключ,<<
который вы не хотите действовать как ключ слияния, например, когда вы делаете сопоставление операторов C с их описаниями на английском (или другом естественном языке).источник
Если вам нужно объединить только один элемент в список, вы можете сделать
что дает
источник
Вы можете объединить сопоставления, а затем преобразовать их ключи в список при следующих условиях:
источник