无法从通过YAML获取的映射中提取键/值对。

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

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[&quot;burger&quot;].([]interface{})
	if !ok {
    // No burger entry  in yaml
		return &quot;&quot;
	}
  debug(&quot;Burger list has %v items:\n%v&quot;, len(b), b)  
  debug(&quot;Type: %v&quot;, reflect.TypeOf(b))
  for i := 0; i &lt; len(b); i++ {
    debug(&quot;%v&quot;, b[i])
  }
 return &quot;&quot;
}
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[&quot;burger&quot;].([]interface{})
if !ok {
  return &quot;&quot;
}

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(&quot;%v&quot;, k)
    v_str := fmt.Sprintf(&quot;%v&quot;, v)

    fmt.Printf(&quot;key %s value %s\n&quot;, k_str, v_str)
  }
}

Starting with the sample code from goldmark-meta, I put together this example:

package main

import (
	&quot;bytes&quot;
	&quot;fmt&quot;

	&quot;github.com/yuin/goldmark&quot;
	meta &quot;github.com/yuin/goldmark-meta&quot;
	&quot;github.com/yuin/goldmark/parser&quot;
)

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), &amp;buf, parser.WithContext(context)); err != nil {
		panic(err)
	}
	metaData := meta.Get(context)
	burger := metaData[&quot;burger&quot;].([]interface{})
	for _, item := range burger {
		for k, v := range item.(map[interface{}]interface{}) {
			k_str := fmt.Sprintf(&quot;%v&quot;, k)
			v_str := fmt.Sprintf(&quot;%v&quot;, v)
			fmt.Printf(&quot;key %s value %s\n&quot;, k_str, v_str)
		}
	}
}

Which outputs:

key a value ay
key b value bee
key c value see

huangapple
  • 本文由 发表于 2023年1月5日 22:57:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75020371.html
匿名

发表评论

匿名网友

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

确定