如何在Golang中迭代遍历所有的YAML值?

huangapple go评论85阅读模式
英文:

How to iterate over all the YAML values in Golang?

问题

我正在尝试理解Golang中的嵌套映射。我有一个如下所示的映射,如何迭代所有的键?

数据:

  • name: "foo"
    bar1: 0
    k1: val1
    k2:
    val2
    val3
    bar2: 1
    k3: val4
    k4: val5
    k3: val4
    k4: val5
英文:

I am trying to understand nested maps in Golang. I have a map like below, how do I iterate over all the keys?

Data:
  - name: "foo"
    bar1: 0
      k1: val1
      k2:
         val2
         val3
    bar2: 1
      k3: val4
      k4: val5
      k3: val4
      k4: val5

答案1

得分: 2

你需要将数据解组为一个映射 (map[interface{}]interface{}map[string]interface{}),然后检查键的值的类型。你可以使用 yaml.v2 包,可能有更清晰的接口来检测值的类型。否则,可以查看下面的示例,它遍历键并打印值:

package main

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"reflect"
	"strings"
)

var data = `
Data:
    - name: "foo"
      bar1: 0
      k1: val1
      k2:
         val2
         val3
      bar2: 1
      k3: val4
      k4: val5
      k5: val5
      k6: val6
`

func printVal(v interface{}, depth int) {
	typ := reflect.TypeOf(v).Kind()
	if typ == reflect.Int || typ == reflect.String {
		fmt.Printf("%s%v\n", strings.Repeat(" ", depth), v)
	} else if typ == reflect.Slice {
		fmt.Printf("\n")
		printSlice(v.([]interface{}), depth+1)
	} else if typ == reflect.Map {
		fmt.Printf("\n")
		printMap(v.(map[interface{}]interface{}), depth+1)
	}

}

func printMap(m map[interface{}]interface{}, depth int) {
	for k, v := range m {
		fmt.Printf("%sKey:%s", strings.Repeat(" ", depth), k.(string))
		printVal(v, depth+1)
	}
}

func printSlice(slc []interface{}, depth int) {
	for _, v := range slc {
		printVal(v, depth+1)
	}
}

func main() {
	m := make(map[string]interface{})

	err := yaml.Unmarshal([]byte(data), &m)
	if err != nil {
		panic(err)
	}
	for k, v := range m {
		fmt.Printf("Key:%s ", k)
		printVal(v, 1)
	}
}

希望对你有帮助!

英文:

You have to unmarshal the data into a map (map[interface{}]interface{} or map[string]interface{}) and then you have to check the type of the values for the keys. You may use the yaml.v2 package and there might be cleaner interfaces which helps to detect the type of the values. Otherwise check the example that iterates over the keys and print the values:

package main
import (
"fmt"
"gopkg.in/yaml.v2"
"reflect"
"strings"
)
var data = `
Data:
- name: "foo"
bar1: 0
k1: val1
k2:
val2
val3
bar2: 1
k3: val4
k4: val5
k5: val5
k6: val6
`
func printVal(v interface{}, depth int) {
typ := reflect.TypeOf(v).Kind()
if typ == reflect.Int || typ == reflect.String {
fmt.Printf("%s%v\n", strings.Repeat(" ", depth), v)
} else if typ == reflect.Slice {
fmt.Printf("\n")
printSlice(v.([]interface{}), depth+1)
} else if typ == reflect.Map {
fmt.Printf("\n")
printMap(v.(map[interface{}]interface{}), depth+1)
}
}
func printMap(m map[interface{}]interface{}, depth int) {
for k, v := range m {
fmt.Printf("%sKey:%s", strings.Repeat(" ", depth), k.(string))
printVal(v, depth+1)
}
}
func printSlice(slc []interface{}, depth int) {
for _, v := range slc {
printVal(v, depth+1)
}
}
func main() {
m := make(map[string]interface{})
err := yaml.Unmarshal([]byte(data), &m)
if err != nil {
panic(err)
}
for k, v := range m {
fmt.Printf("Key:%s ", k)
printVal(v, 1)
}
}

huangapple
  • 本文由 发表于 2016年4月21日 17:48:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/36765842.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定