将展平的json转换为嵌套的json

时间:2017-09-25 12:43:02

标签: json go

目前我正在使用以下代码将嵌套的json转换为flattened json:

import (
    "fmt"

    "github.com/nytlabs/gojsonexplode"
)
func main() {
    input := `{"person":{"name":"Joe", "address":{"street":"123 Main St."}}}`
    out, err := gojsonexplode.Explodejsonstr(input, ".")
    if err != nil {
        // handle error
    }
    fmt.Println(out)
}

这是输出:{"person.address.street":"123 Main St.","person.name":"Joe"}

经过一些处理后,现在我想将这些数据恢复到普通的嵌套json中,但我无法这样做。

我最接近的猜测是使用嵌套地图,但我不知道如何使用N级创建嵌套地图。

编辑:为什么我需要这个:我在Redis中存储数据,如果我将json存储到Redis中,那么我就无法搜索密钥,这就是我将密钥转换为key1:key2:key3: some_value

的原因

2 个答案:

答案 0 :(得分:4)

为了“取消”数据,您需要分割点上的每个键并创建嵌套对象。 Here is an example将您的数据放在Go Playground上。

func unflatten(flat map[string]interface{}) (map[string]interface{}, error) {
    unflat := map[string]interface{}{}

    for key, value := range flat {
        keyParts := strings.Split(key, ".")

        // Walk the keys until we get to a leaf node.
        m := unflat
        for i, k := range keyParts[:len(keyParts)-1] {
            v, exists := m[k]
            if !exists {
                newMap := map[string]interface{}{}
                m[k] = newMap
                m = newMap
                continue
            }   

            innerMap, ok := v.(map[string]interface{})
            if !ok {
                return nil, fmt.Errorf("key=%v is not an object", strings.Join(keyParts[0:i+1], "."))
            }   
            m = innerMap
        }   

        leafKey := keyParts[len(keyParts)-1]
        if _, exists := m[leafKey]; exists {
            return nil, fmt.Errorf("key=%v already exists", key)
        }   
        m[keyParts[len(keyParts)-1]] = value
    }   

    return unflat, nil 
} 

答案 1 :(得分:-1)

json.MarshalIndent是你的朋友。

j, err := json.MarshalIndent(x, "", "\t")
if err != nil {
    log.Println(err)
}
log.Println(string(j))

它将以缩进的方式打印您的数据(x)。