Saya ingin menggabungkan array di YAML, dan memuatnya melalui ruby -
some_stuff: &some_stuff
- a
- b
- c
combined_stuff:
<<: *some_stuff
- d
- e
- f
Saya ingin memiliki array gabungan sebagai [a,b,c,d,e,f]
Saya menerima kesalahan: tidak menemukan kunci yang diharapkan saat mengurai pemetaan blok
Bagaimana cara menggabungkan array di YAML?
list
data-structures
yaml
lfender6445.dll
sumber
sumber
Jawaban:
Jika tujuannya adalah untuk menjalankan urutan perintah shell, Anda mungkin dapat melakukannya sebagai berikut:
Ini sama dengan:
Saya telah menggunakan ini di
gitlab-ci.yml
(untuk menjawab komentar @ rink.attendant.6 pada pertanyaan).Contoh kerja yang kami gunakan untuk mendukung
requirements.txt
memiliki repos pribadi dari gitlab:dimana
requirements_test.txt
berisi mis-e git+ssh://[email protected]/example/[email protected]#egg=example
sumber
Perbarui: 2019-07-01 14:06:12
Konteks
Posting ini mengasumsikan konteks berikut:
Masalah
lfender6445 ingin menggabungkan dua atau lebih daftar dalam file YAML, dan membuat daftar yang digabungkan tersebut muncul sebagai satu daftar tunggal ketika diurai.
Solusi (Solusi)
Ini dapat diperoleh hanya dengan menetapkan jangkar YAML ke pemetaan, di mana daftar yang diinginkan muncul sebagai elemen turunan dari pemetaan. Ada peringatan untuk ini, bagaimanapun, (lihat "Jebakan" infra).
Pada contoh di bawah ini kami memiliki tiga pemetaan (
list_one, list_two, list_three
) dan tiga jangkar dan alias yang merujuk ke pemetaan ini jika sesuai.Ketika file YAML dimuat dalam program, kita mendapatkan daftar yang kita inginkan, tetapi mungkin memerlukan sedikit modifikasi setelah memuat (lihat perangkap di bawah).
Contoh
File YAML asli
Hasil setelah YAML.safe_load
Jebakan
Kesimpulan
Pendekatan ini memungkinkan pembuatan daftar gabungan dengan menggunakan alias dan fitur jangkar dari YAML.
Meskipun hasil keluaran adalah daftar daftar bertingkat, ini dapat dengan mudah diubah menggunakan
flatten
metode.Lihat juga
Pendekatan alternatif yang diperbarui oleh @Anthon
Contoh
flatten
metodeflatten
;; Gabungkan / ratakan larik arrayflatten
;; http://ruby-doc.org/core-2.2.2/Array.html#method-i-flattenflatten
;; https://softwareengineering.stackexchange.com/a/254676/23884sumber
Ini tidak akan berhasil:
penggabungan hanya didukung oleh spesifikasi YAML untuk pemetaan dan bukan untuk urutan
Anda benar-benar mencampur hal-hal dengan memiliki kunci gabungan
<<
diikuti oleh pemisah kunci / nilai:
dan nilai yang merupakan referensi dan kemudian melanjutkan dengan daftar di tingkat indentasi yang samaIni bukan YAML yang benar:
Jadi contoh sintaks Anda bahkan tidak akan masuk akal sebagai proposal ekstensi YAML.
Jika Anda ingin melakukan sesuatu seperti menggabungkan beberapa array, Anda mungkin ingin mempertimbangkan sintaks seperti:
di mana
s1
,s2
,s3
adalah jangkar pada urutan (tidak ditampilkan) bahwa Anda ingin menggabungkan menjadi urutan baru dan kemudian memilikid
,e
danf
ditambahkan ke itu. Namun YAML menyelesaikan jenis kedalaman struktur ini terlebih dahulu, jadi tidak ada konteks nyata yang tersedia selama pemrosesan kunci penggabungan. Tidak ada larik / daftar yang tersedia untuk Anda di mana Anda dapat melampirkan nilai yang diproses (urutan berlabuh) ke.Anda dapat mengambil pendekatan seperti yang diusulkan oleh @dreftymac, tetapi ini memiliki kerugian besar bahwa Anda perlu mengetahui urutan bersarang mana yang harus diratakan (yaitu dengan mengetahui "jalur" dari akar struktur data yang dimuat ke urutan induk), atau bahwa Anda secara rekursif menjalankan struktur data yang dimuat untuk mencari larik / daftar bersarang dan meratakan semuanya tanpa pandang bulu.
Solusi yang lebih baik IMO adalah menggunakan tag untuk memuat struktur data yang melakukan perataan untuk Anda. Hal ini memungkinkan untuk dengan jelas menunjukkan apa yang perlu diratakan dan apa yang tidak dan memberi Anda kendali penuh atas apakah perataan ini dilakukan selama pemuatan, atau dilakukan selama akses. Yang mana yang harus dipilih adalah soal kemudahan implementasi dan efisiensi waktu dan ruang penyimpanan. Ini adalah trade-off yang sama yang perlu dilakukan untuk menerapkan fitur kunci gabungan dan tidak ada solusi tunggal yang selalu terbaik.
Misalnya
ruamel.yaml
perpustakaan saya menggunakan brute force merge-dicts selama pemuatan saat menggunakan safe-loader, yang menghasilkan kamus gabungan yang merupakan dicts Python normal. Penggabungan ini harus dilakukan di muka, dan data duplikat (ruang tidak efisien) tetapi cepat dalam pencarian nilai. Saat menggunakan round-trip-loader, Anda ingin dapat membuang penggabungan yang tidak digabungkan, sehingga harus tetap dipisahkan. Diktekan seperti struktur data yang dimuat sebagai hasil dari pemuatan bolak-balik, hemat ruang tetapi aksesnya lebih lambat, karena perlu mencoba dan mencari kunci yang tidak ditemukan dalam dikt itu sendiri dalam penggabungan (dan ini tidak di-cache, jadi itu perlu dilakukan setiap saat). Tentu saja pertimbangan seperti itu tidak terlalu penting untuk file konfigurasi yang relatif kecil.Berikut ini mengimplementasikan skema seperti penggabungan untuk daftar di python menggunakan objek dengan tag
flatten
yang dengan cepat muncul kembali menjadi item yang daftar dan diberi tagtoflatten
. Dengan menggunakan dua tag ini, Anda dapat memiliki file YAML:(penggunaan urutan aliran vs gaya blok benar-benar sewenang-wenang dan tidak memiliki pengaruh pada hasil yang dimuat).
Saat mengulangi item yang merupakan nilai untuk kunci
m1
ini "berulang" ke dalam urutan yang diberi tagtoflatten
, tetapi menampilkan daftar lain (alias atau tidak) sebagai satu item.Salah satu cara yang mungkin dengan kode Python untuk mencapainya adalah:
keluaran yang mana:
Seperti yang Anda lihat, Anda dapat melihat, dalam urutan yang perlu diratakan, Anda dapat menggunakan alias ke urutan yang diberi tag atau Anda dapat menggunakan urutan yang diberi tag. YAML tidak mengizinkan Anda melakukan:
, yaitu menandai urutan berlabuh, karena ini pada dasarnya akan membuatnya menjadi struktur data yang berbeda.
Menggunakan tag eksplisit IMO lebih baik daripada melakukan keajaiban seperti pada kunci gabungan YAML
<<
. Jika tidak ada lagi Anda sekarang harus melalui rintangan jika Anda kebetulan memiliki file YAML dengan pemetaan yang memiliki kunci<<
yang Anda tidak ingin bertindak seperti kunci gabungan, misalnya ketika Anda membuat pemetaan operator C ke deskripsinya dalam bahasa Inggris (atau bahasa alami lainnya).sumber
Jika Anda hanya perlu menggabungkan satu item ke dalam daftar, Anda dapat melakukannya
yang menghasilkan
sumber
Anda dapat menggabungkan pemetaan lalu mengubah kuncinya menjadi daftar, dengan ketentuan berikut:
sumber