英文:
Unable to extract key/value pairs from a map obtained through YAML
问题
我使用goldmark-meta包来读取一个YAML文件。我对YAML中的内容感兴趣,它看起来像这样:
burger:
- a: ay
- b: bee
- c: see
我想要访问返回接口的键和值,但我卡住了。通过迭代返回值,我得到了一个键/值对的列表,但是当我不知道键名时,我不知道如何获取任何信息。这个程序输出如下:
func (c *config) burger() string {
    // c.pageFm is type map[string]interface{}
	b, ok := c.pageFm["burger"].([]interface{})
	if !ok {
    // No burger entry  in yaml
		return ""
	}
  debug("Burger list has %v items:\n%v", len(b), b)  
  debug("Type: %v", reflect.TypeOf(b))
  for i := 0; i < len(b); i++ {
    debug("%v", b[i])
  }
 return ""
}
Burger list has 3 items:
[map[a:ay] map[b:bee] map[c:see]]
Type: []interface {}
map[a:ay]
map[b:bee]
map[c:see]
我该如何获取键和值字符串?
英文:
I use the goldmark-meta package to read a YAML file.
The contents  I'm interested in look like this
in the YAML:
burger:
- a: ay
- b: bee
- c: see
I want to get access to both keys and values
of the returned interface, and I'm stuck.
Iterating through the return gives me a
list of the key/value pairs, but I don't
know how to obtain any info when I don't
know the key names in advance.
This program prints out the following:
func (c *config) burger() string {
    // c.pageFm is type map[string]interface{}
	b, ok := c.pageFm["burger"].([]interface{})
	if !ok {
    // No burger entry  in yaml
		return ""
	}
  debug("Burger list has %v items:\n%v", len(b), b)  
  debug("Type: %v", reflect.TypeOf(b))
  for i := 0; i < len(b); i++ {
    debug("%v", b[i])
  }
 return ""
}
Burger list has 3 items:
[map[a:ay] map[b:bee] map[c:see]]
Type: []interface {}
map[a:ay]
map[b:bee]
map[c:see]
How do I obtain the key and value strings?
答案1
得分: 1
在您的YAML数据中,有一个键(burger),其值是一个包含映射的列表(每个映射只有一个键)。我们可以像这样迭代burger中的项:
b, ok := c.pageFm["burger"].([]interface{})
if !ok {
  return ""
}
for _, item := range burger {
  ...
}
对于每个item,我们可以迭代可用的键和值:
for _, item := range burger {
  for k, v := range item.(map[interface{}]interface{}) {
    ...
  }
}
我们可以使用fmt.Sprintf将键和值从interface{}转换为string:
for _, item := range burger {
  for k, v := range item.(map[interface{}]interface{}) {
    k_str := fmt.Sprintf("%v", k)
    v_str := fmt.Sprintf("%v", v)
    fmt.Printf("key %s value %s\n", k_str, v_str)
  }
}
从goldmark-meta的示例代码开始,我组合了这个示例:
package main
import (
	"bytes"
	"fmt"
	"github.com/yuin/goldmark"
	meta "github.com/yuin/goldmark-meta"
	"github.com/yuin/goldmark/parser"
)
func main() {
	markdown := goldmark.New(
		goldmark.WithExtensions(
			meta.Meta,
		),
	)
	source := `---
burger:
- a: ay
- b: bee
- c: see
---
# Hello goldmark-meta
`
	var buf bytes.Buffer
	context := parser.NewContext()
	if err := markdown.Convert([]byte(source), &buf, parser.WithContext(context)); err != nil {
		panic(err)
	}
	metaData := meta.Get(context)
	burger := metaData["burger"].([]interface{})
	for _, item := range burger {
		for k, v := range item.(map[interface{}]interface{}) {
			k_str := fmt.Sprintf("%v", k)
			v_str := fmt.Sprintf("%v", v)
			fmt.Printf("key %s value %s\n", k_str, v_str)
		}
	}
}
输出结果为:
key a value ay
key b value bee
key c value see
英文:
In your YAML data, you have a key (burger) the value of which is a list of maps (and each map has a single key). We can iterate over the items in burger like this:
b, ok := c.pageFm["burger"].([]interface{})
if !ok {
  return ""
}
for _, item := range burger {
  ...
}
For each item, we can iterate over available keys and values:
for _, item := range burger {
  for k, v := range item.(map[interface{}]interface{}) {
    ...
  }
}
We can convert keys and values from interface{} into string using fmt.Sprintf:
for _, item := range burger {
  for k, v := range item.(map[interface{}]interface{}) {
    k_str := fmt.Sprintf("%v", k)
    v_str := fmt.Sprintf("%v", v)
    fmt.Printf("key %s value %s\n", k_str, v_str)
  }
}
Starting with the sample code from goldmark-meta, I put together this example:
package main
import (
	"bytes"
	"fmt"
	"github.com/yuin/goldmark"
	meta "github.com/yuin/goldmark-meta"
	"github.com/yuin/goldmark/parser"
)
func main() {
	markdown := goldmark.New(
		goldmark.WithExtensions(
			meta.Meta,
		),
	)
	source := `---
burger:
- a: ay
- b: bee
- c: see
---
# Hello goldmark-meta
`
	var buf bytes.Buffer
	context := parser.NewContext()
	if err := markdown.Convert([]byte(source), &buf, parser.WithContext(context)); err != nil {
		panic(err)
	}
	metaData := meta.Get(context)
	burger := metaData["burger"].([]interface{})
	for _, item := range burger {
		for k, v := range item.(map[interface{}]interface{}) {
			k_str := fmt.Sprintf("%v", k)
			v_str := fmt.Sprintf("%v", v)
			fmt.Printf("key %s value %s\n", k_str, v_str)
		}
	}
}
Which outputs:
key a value ay
key b value bee
key c value see
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论