亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Golang 中向嵌套的 map[string]interface{} 添加屬性

在 Golang 中向嵌套的 map[string]interface{} 添加屬性

Go
拉丁的傳說 2023-07-31 15:31:05
我正在處理 類型的數據map[string]interface{}。它可以在 (map[string]interface{}) 類型內擁有無限數量的嵌套對象。編輯: 此數據來自 mongodb。我不能在這里真正應用 golang 的結構,因為屬性因文檔而異。我想要做的就是獲取最深嵌套的對象,向其添加新屬性并確保之后更新整個數據對象。data["person"] = map[string]interface{}{    "peter": map[string]interface{}{        "scores": map[string]interface{}{            "calculus": 88,            "algebra":  99,            "golang":   89,        },    },}這些數據來自遠程 API,我不知道里面的屬性。我想添加的只是在最后一個對象(在本例中為“分數”)內添加新屬性,并且可以說使用這個新屬性(“物理”),數據將如下所示data["person"] = map[string]interface{}{    "peter": map[string]interface{}{        "scores": map[string]interface{}{            "calculus": 88,            "algebra":  99,            "golang":   89,            "physics":  95,        },    },}我不確定如何將該屬性添加到最后一個對象中。我進行了遞歸類型檢查,并且能夠獲取每個字段并打印其值。但是,由于映射不是引用性的,因此當我使用非復雜類型的值到達映射時,我無法向原始映射添加值。package mainimport "fmt"func main() {    data := make(map[string]interface{})    data["person"] = map[string]interface{}{        "peter": map[string]interface{}{            "scores": map[string]interface{}{                "calculus": 88,                "algebra":  99,                "golang":   89,            },        },    }    parseMap(data)}func parseMap(aMap map[string]interface{}) interface{} {    var retVal interface{}    for _, val := range aMap {        switch val.(type) {        case map[string]interface{}:            retVal = parseMap(val.(map[string]interface{}))        //case []interface{}:        //  retVal = parseArray(val.([]interface{}))        default:            //here i would have done aMap["physics"] = 95 if I could access the original map by reference, but that is not possible            retVal = aMap        }    }    return retVal}
查看完整描述

2 回答

?
收到一只叮咚

TA貢獻1821條經驗 獲得超5個贊

根據對該問題的評論,目標是在最深層嵌套的映射中設置一個值。


使用以下函數查找最大嵌套級別的映射。如果最大嵌套級別有多個映射,則此函數返回這些映射中的任意一個。


func findDeepest(m map[string]interface{}) (int, map[string]interface{}) {

    depth := 0

    candidate := m

    for _, v := range m {

        if v, ok := v.(map[string]interface{}); ok {

            d, c := findDeepest(v)

            if d+1 > depth {

                depth = d + 1

                candidate = c

            }

        }

    }

    return depth, candidate

}

像這樣使用它在深度嵌套映射中設置一個值:


_, m := findDeepest(data)

m["physics"] = 95

在操場上運行它。



查看完整回答
反對 回復 2023-07-31
?
繁星coding

TA貢獻1797條經驗 獲得超4個贊

map[string]interface{}盡量避免使用原始類型。Goencoding/json文件可以很好地處理字符串鍵控的映射,并且希望遠程 API對于您正在處理的內容有某種規范。(例如,您知道您需要一個person頂級密鑰并且位于層次結構中的特定點。)scores


我假設遠程 API 是 JSON-over-HTTP。您可以將其結構建模為


type Input struct {

    Person map[string]Person `json:"person"`

}


type Person struct {

    Scores map[string]int `json:"scores"`

}

將json.Unmarshal()數據寫入此結構后,您可以直接設置


data.Person["peter"].Scores["physics"] = 95

然后json.Marshal()再次得到結果。 https://play.golang.org/p/qoAVFodSvK2有一個完整的示例。


如果您確實想直接操作map[string]interface{}結構,我建議將每個“級別”拆分為單獨的函數調用


func ParseTopLevel(data map[string]interface{}) {

    switch peter := data["peter"].(type) {

    case map[string]interface{}:

        ParsePeter(peter)

    }

}

map類型是通過引用傳遞的,因此當到達堆棧底部時可以直接設置scores["physics"] = 95。(在您的原始代碼中,如果您無法按照aMap["physics"]您的建議直接設置,我會感到驚訝,盡管設置的內容相當不精確;比較https://play.golang.org/p/VuTjcjezwwU。)


查看完整回答
反對 回復 2023-07-31
  • 2 回答
  • 0 關注
  • 563 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號