在Go中保存YAML文件中的顺序

wkyowqbh  于 2023-04-18  发布在  Go
关注(0)|答案(2)|浏览(163)

我试图读取YAML文件中的数据,它看起来像这样:

Category Name:
  Task 1:
    Name: Meeting
    PM: 1
    TC: 0
    STC: 1
    Optional: false

在一个类别中可以有多个任务,也可以有多个类别。

type Task struct {
    Name     string
    PM       string
    TC       string
    STC      string
    Optional bool
}
type Category struct {
    Name  string
    Tasks []Task
}
func parseFile() map[string]map[string]map[string]string {
    file, err := ioutil.ReadFile("config.yaml")

    if err != nil {
        log.Fatal(err)
    }

    data := make(map[string]map[string]map[string]string)
    err1 := yaml.Unmarshal(file, &data)

    if err1 != nil {
        log.Fatal(err1)
    }

    return data
}

然后我只需要一个函数来循环遍历parseFile()中创建的Map,并创建一个包含填充信息的Category列表,这非常好用......除了因为Map没有排序而导致YAML文件中编写的类别/任务的顺序没有保留。
通过在线阅读,我发现你可以使用www.example.com上的yaml.MapSlice{}来保留顺序gokpg.in/yaml.v2。然而,我不知道如何处理这个结果MapSlice。我可以迭代它来获得类别,但我不能迭代.Value,因为MapItem是接口,但是MapItems会存储我的任务列表。我能做什么才能得到任务并放入[]任务?
感谢帮助:)

dy2hfwbg

dy2hfwbg1#

我设法通过改变YAML和结构的格式来解决这个问题,然后直接解编到结构中。
新的结构。

type Categories struct {
    Category []struct {
        Name string `yaml:"CategoryName"`
        Task []struct {
            Name     string  `yaml:"TaskName"`
            PM       float64 `yaml:"PM"`
            TC       float64 `yaml:"TC"`
            STC      float64 `yaml:"STC"`
            Optional bool    `yaml:"Optional"`
        } `yaml:"Tasks"`
    } `yaml:"Categories"`
}

YAML文件的新格式,以支持结构中的内容。

Categories:
  - CategoryName: Category 1
    Tasks:
      - TaskName: Test 1
        PM: 1
        TC: 0
        STC: 1
        Optional: false
      - TaskName: Test 2
        PM: 2
        TC: 0
        STC: 2
        Optional: false
  - CategoryName: Category 2
    Tasks:
      - TaskName: Test 3
        PM: 1
        TC: 2
        STC: 3
        Optional: true

将YAML文件直接解组为新结构

var tasks Categories
    file, err := ioutil.ReadFile("config.yaml")

    if err != nil {
        log.Fatal(err)
    }

    yaml.Unmarshal(file, &tasks)

这解决了我的问题--不再使用Map,这样顺序就被保留了,并以一种我觉得很容易循环的方式使用结构。

4c8rllxm

4c8rllxm2#

package main

import (
    "fmt"
    "gopkg.in/yaml.v2"
    "io/ioutil"
    "log"
)

type Config struct {
    CategoryName []map[string]Task `yaml:"CategoryName"`
}

type Task struct {
    Name string `yaml:"Name"`
    PM int `yaml:"PM"`
    TC int `yaml:"TC"`
    STC int `yaml:"STC"`
    Optional bool  `yaml:"Optional"`
}

func main() {
    yamlData := []byte(`
CategoryName:
  - Task1:
      Name: "Meeting"
      PM: 1
      TC: 0
      STC: 1
      Optional: false
  - Task2:
      Name: "Meeting v2"
      PM: 2
      TC: 0
      STC: 2
      Optional: false
`)

    var config Config
    err := yaml.Unmarshal(yamlData, &config)
    if err != nil {
        log.Fatalf("Erreur lors de la décomposition du YAML : %v", err)
    }

    fmt.Printf("Configuration : %+v\n", config)
}

相关问题