How to merge YAML arrays?
I would like to merge arrays in YAML, and load them via ruby -
some_stuff: &some_stuff
- a
- b
- c
combined_stuff:
<<: *some_stuff
- d
- e
- f
I'd like to have the combined array as [a,b,c,d,e,f]
I receive the error: did not find expected key while parsing a block mapping
How do I merge arrays in YAML?
If the aim is to run a sequence of shell commands, you may be able to achieve this as follows:
# note: no dash before commands
some_stuff: &some_stuff |-
a
b
c
combined_stuff:
- *some_stuff
- d
- e
- f
This is equivalent to:
some_stuff: "a\nb\nc"
combined_stuff:
- "a\nb\nc"
- d
- e
- f
I have been using this on my gitlab-ci.yml
(to answer @rink.attendant.6 comment on the question).
Working example that we use to support requirements.txt
having private repos from gitlab:
.pip_git: &pip_git
- git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com".insteadOf "ssh://[email protected]"
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
test:
image: python:3.7.3
stage: test
script:
- *pip_git
- pip install -q -r requirements_test.txt
- python -m unittest discover tests
use the same `*pip_git` on e.g. build image...
where requirements_test.txt
contains e.g.
-e git+ssh://[email protected]/example/[email protected]#egg=example
Update: 2019-07-01 14:06:12
-
Note: another answer to this question was substantially edited with an update on alternative approaches.
- That updated answer mentions an alternative to the workaround in this answer. It has been added to the See also section below.
Context
This post assumes the following context:
- python 2.7
- python YAML parser
Problem
lfender6445 wishes to merge two or more lists within a YAML file, and have those merged lists appear as one singular list when parsed.
Solution (Workaround)
This may be obtained simply by assigning YAML anchors to mappings, where the desired lists appear as child elements of the mappings. There are caveats to this, however, (see "Pitfalls" infra).
In the example below we have three mappings (list_one, list_two, list_three
) and three anchors
and aliases that refer to these mappings where appropriate.
When the YAML file is loaded in the program we get the list we want, but it may require a little modification after load (see pitfalls below).
Example
Original YAML file
list_one: &id001 - a - b - c list_two: &id002 - e - f - g list_three: &id003 - h - i - j list_combined: - *id001 - *id002 - *id003
Result after YAML.safe_load
## list_combined [ [ "a", "b", "c" ], [ "e", "f", "g" ], [ "h", "i", "j" ] ]
Pitfalls
- this approach produces a nested list of lists, which may not be the exact desired output, but this can be post-processed using the flatten method
- the usual caveats to YAML anchors and aliases apply for uniqueness and declaration order
Conclusion
This approach allows creation of merged lists by use of the alias and anchor feature of YAML.
Although the output result is a nested list of lists, this can be easily transformed using the flatten
method.
See also
Updated alternative approach by @Anthon
- See alternative approach
Examples of the flatten
method
- Javascript
flatten
;; Merge/flatten an array of arrays - Ruby
flatten
;; http://ruby-doc.org/core-2.2.2/Array.html#method-i-flatten - Python
flatten
;; https://softwareengineering.stackexchange.com/a/254676/23884