如何将 map[string]interface{} 数据转换为结构

how to convert map[string]interface{} data to struct

我不会问,举个例子问吧

我有一些这样的数据

{
..
    "velocityStatEntries":  {

    "8753":  {

        "estimated":  {"value":  23.0,"text":  "23.0"},

        "completed":  {"value":  27.0,"text":  "27.0"}
    },

    "8673":  {

        "estimated":  {"value":  54.5,"text":  "54.5"},

        "completed":  {"value":  58.5,"text":  "58.5"}
    },
    .
    .
    .

    }
..
}

我想声明一个类型,该类型将映射键作为其“KEY”或我提供的任何 属性。 不使用地图迭代是否可行?

预期输出:

{...
   "velocityStatEntries": {
   {
     "key": "8753",
     "estimated":  {"value":  54.5,"text":  "54.5"},
     "completed":  {"value":  58.5,"text":  "58.5"}
   },
   {
     "key": "8673",
     "estimated":  {"value":  54.5,"text":  "54.5"},
     "completed":  {"value":  58.5,"text":  "58.5"}
   },
  }
...
}

这就是我所做的

type VelocityStatEntry struct {
    Key string
    Estimated struct {
        Value float64 `json:"value"`
        Text  string  `json:"text"`
    } `json:"estimated"`
    Completed struct {
        Value float64 `json:"value"`
        Text  string  `json:"text"`
    } `json:"completed"`
}

type RapidChartResponse struct {
    ...
    VelocityStatEntries map[string]VelocityStatEntry `json:"velocityStatEntries"`
    ..
}

但它不起作用。我想将该字符串映射键带到 KEY 属性.

如果数据来自 JSON,那么您应该跳过 map[string]interface{},而是使用由您想要的结构实现的 custom unmarshaler 来执行您想要的操作。也许通过使用 map[string]json.RawMessage。但是 map[string]interface{} 结构转换很痛苦,尽可能避免。

例如:

type VelocityStatEntryList []*VelocityStatEntry

func (ls *VelocityStatEntryList) UnmarshalJSON(data []byte) error {
    var m map[string]json.RawMessage
    if err := json.Unmarshal(data, &m); err != nil {
        return err
    }
    for k, v := range m {
        e := &VelocityStatEntry{Key: k}
        if err := json.Unmarshal([]byte(v), e); err != nil {
            return err
        }
        *ls = append(*ls, e)
    }
    return nil
}

https://go.dev/play/p/VcaW_BWXRVr