【问题标题】:How to convert entire nested struct into map如何将整个嵌套结构转换为地图
【发布时间】:2020-12-14 00:52:03
【问题描述】:

我有一个场景,我必须将整个结构转换为地图。 我知道我们有一个库 structs.Map(s) 可以将结构转换为地图。但我想知道有没有一种方法可以将结构内的多个结构转换为映射 [字符串] 接口。 例如我们有以下

package main

import (
    "log"

    "github.com/fatih/structs"
)

type Community struct {
    Name        string   `json:"name,omitempty"`
    Description string   `json:"description,omitempty"`
    Sources     []Source `json:"sources,omitempty"`
    Moderators  []string `json:"moderators,omitempty"`
}

type Source struct {
    SourceName string  `json:"sourceName,omitempty"`
    Region []State `json:"region,omitempty"`
}

type State struct {
    State1 string `json:"state1,omitempty"`
    State2 string `json:"state2,omitempty"`
}

func main() {

    compareData := Community{
        Name:        "A",
        Description: "this belong to A community",
        Sources: []Source{
            {
                SourceName: "SourceA",
                Region: []State{
                    {
                        State1: "State1",
                    },
                    {
                        State2: "State2",
                    },
                },
            },
        },
    }
    m := structs.Map(compareData)
    log.Println(m)
}

这将给出如下结果,即再次为内部结构创建映射

map[Description:this belong to A community 
Moderators:[] 
Name:A Sources:[map[SourceName:SourceA Region:[map[State1:State1 State2:] map[State1: State2:State2]]]]]

我的期望是只得到一个 map[string]interface{}

map[
Description:this belong to A community 
Moderators:[] 
Name:A 
SourceName:SourceA 
State1:State1 
State2:State2
]

我创建单个映射的目的是将值与基于 key 的不同映射进行比较。 我的结构也根据不同的响应而变化,所以我想要一个地图,我可以在其中获取所有键值对以便于比较。如果有人对此有建议,请告诉我。

【问题讨论】:

  • 使用reflect.DeepEqual() 比较原始结构或从它们创建的嵌套映射。
  • 地图中的键必须是唯一的,因此Name:AName:SourceA 中的map[string]interface{} 永远不会发生。
  • 我认为最好的方法是在结构中使用嵌套比较,而不仅仅是转换为映射
  • 是的,键必须是唯一的,这只是我为进入单个地图而编写的示例

标签: dictionary go struct


【解决方案1】:

您可以使用mapstructure 包。

使用示例:

package main

import (
    "fmt"
    "github.com/mitchellh/mapstructure"
)

func main() {

    type Emails struct {
        Mail []string
    }

    type Person struct {
        Name   string
        Age    int
        Emails Emails
        Extra  map[string]string
    }



    // This input can come from anywhere, but typically comes from
    // something like decoding JSON where we're not quite sure of the
    // struct initially.
    mails := []string{"foo@bar.com", "foo2@bar.com"}
    input := Person{
        Name:   "foo",
        Age:    25,
        Emails: Emails{Mail: mails},
        Extra:  map[string]string{"family": "bar"},
    }

    result := map[string]interface{}{}

    err := mapstructure.Decode(input, &result)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%#v", result)
}


playground

【讨论】:

    猜你喜欢
    • 2018-03-15
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多