Rumah > Artikel > pembangunan bahagian belakang > Gabungkan dua hierarki pemetaan daripada fail YAML, mengekalkan semua kunci
Dalam artikel ini, editor PHP Xigua akan memperkenalkan cara menggabungkan dua hierarki pemetaan daripada fail YAML dan mengekalkan semua kunci. Prosesnya sangat mudah dan hanya memerlukan penggunaan fungsi dan kaedah yang sesuai. Dengan menggabungkan dua hierarki pemetaan, kami boleh menggabungkan kunci dan nilai mereka untuk mencipta hierarki pemetaan yang lebih besar dan lebih komprehensif. Sama ada anda bekerja dengan fail konfigurasi atau pemprosesan data, penggabungan hierarki pemetaan ialah teknik yang sangat berguna. Seterusnya, kami akan membimbing anda melalui proses langkah demi langkah supaya anda boleh menguasai teknik ini dengan mudah.
Saya sedang mengusahakan penyelesaian yang melibatkan kunci bersarang dalam fail yaml. Perisian akan membaca fail yang diluluskan dalam parameter dan memuatkannya dalam susunan kekunci dikemas kini/ditambah.
Saya mempunyai 2 fail yaml dan saya mahu menggabungkannya tanpa kehilangan sebarang kunci. Saya mahu menyusun semua profil untuk menjana satu peta tanpa mengeluarkan sebarang kekunci.
Jadi saya ada yaml 1
env: test1 template: app: database: name: oracle
yaml2
env: test2 template: app: database: version : 12
Hasil yang saya nak ialah (tempahan yaml1 - yaml2)
env: test2 template: app: database: name: oracle version: 12
Saya cuba menyalin menggunakan peta tetapi memandangkan kekunci mempunyai nama yang sama, saya mendapat
env: test2 template: app: database: version: 12
Saya menggunakan
gopkg.in/yaml.v3 untuk membaca yaml memberikan saya antara muka[rentetan] peta{}
dan peta menggunakan salinan
package main import ( "fmt" "log" "maps" "os" "path/filepath" "gopkg.in/yaml.v3" ) type configuration struct { c m fl []string } type m = map[string]interface{} func (c *configuration) Update(nc m) { if c.c == nil { c.c = nc } else { maps.Copy(c.c, nc) } } func (c configuration) Print() { d, err := yaml.Marshal(&c.c) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("---:\n%s\n\n", string(d)) } func (c configuration) ParseDir(path string) { } func (c *configuration) LoadFromFile(filename string) { // YAML string stored in a variable yf, yfErr := os.ReadFile(filename) if yfErr != nil { log.Fatal("Error reading the file ", yfErr) } // Map to store the parsed YAML data var data m // Unmarshal the YAML string into the data map err := yaml.Unmarshal(yf, &data) if err != nil { log.Fatal(err) } c.Update(data) } func listFiles(path string) []string { var returnLf []string err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.Mode().IsRegular() { returnLf = append(returnLf, path) } return nil }) if err != nil { log.Println(err) } return returnLf }
Andaikan anda ingin menggabungkan peta YAML yang dikunci oleh "template" daripada dua dokumen YAML, pelaksanaan yang agak mudah akan kelihatan seperti ini:
package main import ( "fmt" "gopkg.in/yaml.v3" ) const data1 = `--- env: test1 template: app: database: name: oracle foo: whatever ` const data2 = `--- env: test2 template: app: some_stuff: [1, 2, 3, 4] database: version : 12 foo: 42 ` type T struct { Env string `yaml:"env"` Tmpl map[string]any `yaml:"template"` } func mergeMapsRecursively(dst, src map[string]any) map[string]any { res := make(map[string]any) for dstKey, dstVal := range dst { srcVal, exists := src[dstKey] if !exists { res[dstKey] = dstVal continue } dstValMap, dstValIsMap := dstVal.(map[string]any) srcValMap, srcValIsMap := srcVal.(map[string]any) if dstValIsMap && srcValIsMap { res[dstKey] = mergeMapsRecursively(dstValMap, srcValMap) } else { res[dstKey] = srcVal } } for srcKey, srcVal := range src { if _, exists := dst[srcKey]; !exists { res[srcKey] = srcVal } } return res } func main() { var a, b T if err := yaml.Unmarshal([]byte(data1), &a); err != nil { panic(err) } if err := yaml.Unmarshal([]byte(data2), &b); err != nil { panic(err) } fmt.Printf("%#v\n%#v\n%#v\n", a.Tmpl, b.Tmpl, mergeMapsRecursively(a.Tmpl, b.Tmpl)) }
mergeMapsRecursively
函数递归地合并两个映射中存在的字段(如果它们都是映射),或者将 dst
中的值替换为 src
中的值,否则 — 就像 maps.Copy
melakukan perkara itu.
Jika ini bukan perkara yang anda minta, saya harap contoh saya akan membawa anda ke landasan yang betul.
Atas ialah kandungan terperinci Gabungkan dua hierarki pemetaan daripada fail YAML, mengekalkan semua kunci. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!