当前位置: 首页 > 面试题库 >

取一个JSON字符串,将其解组到map [string] interface {}中,进行编辑,然后将其编组为[] byte似乎要复杂得多,

夏飞鹏
2023-03-14
问题内容

我正在做非常基本的JSON操作来学习Go语言,并且可以正常工作,除非似乎有一件事情,我必须编写JSON的分配.(map[string]interface{}).([]interface{})访问JSON中的条目,尤其是当它们是孩子的孩子时,等等。

参见此处(也在Go Playground上:https :
//play.golang.org/p/Wd-pzHqTsU):

package main

import (
    "fmt"
    "encoding/json"
)

func main() {
    JSON := []byte(`{"key1":"val1","key2":{"c1key1":"c1val1"},"key3":[{"c2key1":{"c3key1":"c3val1"}}]}`)
    fmt.Printf("%s\n", JSON)
    var d map[string]interface{}
    json.Unmarshal(JSON, &d)
    fmt.Println(d["key3"].([]interface{})[0].(map[string]interface{})["c2key1"].(map[string]interface{})["c3key1"])
    d["key3"].([]interface{})[0].(map[string]interface{})["c2key1"].(map[string]interface{})["c3key1"] = "change1"
    fmt.Println(d["key3"].([]interface{})[0].(map[string]interface{})["c2key1"].(map[string]interface{})["c3key1"])
    JSON, _ = json.Marshal(d)
    fmt.Printf("%s\n", JSON)
}

哪个返回:

{"key1":"val1","key2":{"c1key1":"c1val1"},"key3":[{"c2key1":{"c3key1":"c3val1"}}]}
c3val1
change1
{"key1":"val1","key2":{"c1key1":"c1val1"},"key3":[{"c2key1":{"c3key1":"change1"}}]}

现在,在Python中,我直接访问键/值,而不是定义每次访问的类型,而不是fmt.Println(d["key3"].([]interface{})[0].(map[string]interface{})["c2key1"].(map[string]interface{})["c3key1"])print d["key3"][0]["c2key1"]["c3key1"]

Python示例:

import json

JSON = '{"key3": [{"c2key1": {"c3key1": "c3val1"}}], "key2": {"c1key1": "c1val1"}, "key1": "val1"}'
print JSON
d = json.loads(JSON)
print d["key3"][0]["c2key1"]["c3key1"]
d["key3"][0]["c2key1"]["c3key1"] = "change1"
print d["key3"][0]["c2key1"]["c3key1"]
JSON = json.dumps(d)
print JSON

那么我在Go中这样做正确吗?如果是这样,此设计的原因是什么?否则,我该怎么办?


问题答案:

前言:
我优化和改进了以下解决方案,并将其作为库发布在这里:github.com/icza/dyno

最干净的html" target="_blank">方法是创建struct对JSON建模的预定义类型(结构),并解组为该类型的值,并且您可以使用Selectors(用于struct类型)和Index表达式(用于地图和切片)简单地引用元素。

但是,如果您的输入不是预定义的结构,则建议您使用以下2个辅助函数:get()set()。第一个访问(返回)由任意路径(string映射键和/或int切片索引的列表)指定的任意元素,第二个访问(返回)由任意路径指定的值(这些帮助函数的实现在最后)答案)。

您只需在项目/应用程序中包含这两个功能。

现在,使用这些帮助器,您想要执行的任务变得非常简单(就像python解决方案一样):

fmt.Println(get(d, "key3", 0, "c2key1", "c3key1"))
set("NEWVALUE", d, "key3", 0, "c2key1", "c3key1")
fmt.Println(get(d, "key3", 0, "c2key1", "c3key1"))

输出:

change1
NEWVALUE

在Go Playground上尝试修改后的应用程序

注意-进一步简化:

您甚至可以将路径保存在变量中,然后重复使用以进一步简化上面的代码:

path := []interface{}{"key3", 0, "c2key1", "c3key1"}

fmt.Println(get(d, path...))
set("NEWVALUE", d, path...)
fmt.Println(get(d, path...))

和的实现get(),并set()在下面。注意:检查路径是否有效被省略。此实现使用类型开关:

func get(m interface{}, path ...interface{}) interface{} {
    for _, p := range path {
        switch idx := p.(type) {
        case string:
            m = m.(map[string]interface{})[idx]
        case int:
            m = m.([]interface{})[idx]
        }
    }
    return m
}

func set(v interface{}, m interface{}, path ...interface{}) {
    for i, p := range path {
        last := i == len(path)-1
        switch idx := p.(type) {
        case string:
            if last {
                m.(map[string]interface{})[idx] = v
            } else {
                m = m.(map[string]interface{})[idx]
            }
        case int:
            if last {
                m.([]interface{})[idx] = v
            } else {
                m = m.([]interface{})[idx]
            }
        }
    }
}


 类似资料:
  • 问题内容: 我正在做非常基本的JSON操作来学习Go语言,并且可以正常工作,除非似乎有一件事情,我必须编写JSON的分配并访问JSON中的条目,尤其是当它们是孩子的孩子时,等等。 参见此处(也在Go Playground上:https : //play.golang.org/p/Wd-pzHqTsU): 哪个返回: 现在,在Python中,我直接访问键/值,而不是定义每次访问的类型,而不是您 Py

  • 在这种情况下,调用是否会返回错误? 我想知道部分是出于好奇,部分是考虑我是否需要担心错误检查。

  • 问题内容: 从来源来看,我无法影响我在地图中获得的数据,该地图以表示。 我需要处理所包含的数据,最好是(其中的数据非常适合该处理)。 我还需要从数据中生成键列表,因为这些键是事先未知的。 我可以在网上找到的大多数类似问题或多或少都说这是不可能的,但是如果我的地图是,则表明数据在那里,可读性为。 我该怎么办fmt.Println可以做什么? 问题答案: 处理未知接口的一种安全方法,只需使用fmt.S

  • 问题内容: 我想更改字节数组中的值以在MSB中放入较长的时间戳值。有人可以告诉我最好的方法是什么。我不想一点一点地插入值,我认为这是非常低效的。 我想要的是这样的: 这样是可能的。在此字节数组中编辑/插入值的最佳方法是什么。由于字节是原始数据,我不认为有一些直接的实现可以利用吗? 编辑: 似乎比快,所以用它替换上面的代码。如果有误,请纠正我。 问题答案: 有多种方法可以做到这一点: 使用(最佳选择

  • 问题内容: 说我有以下代码: 在这种情况下,有什么办法可以使调用返回错误? 我想知道,部分原因是出于好奇,另一部分是考虑是否需要担心该错误检查。 问题答案: 由于任何有效值都是有效键,而且也是JSON中的有效值(有关详细信息,请参阅JSON键名中的哪些字符有效/无效?,因此从理论上讲,它不会返回任何错误。 如果发生内存不足错误,则不会返回错误,您的应用将终止并显示错误代码。 由于Go将值存储为其U

  • 问题内容: 我有两个字符串数组键和值 将它们转换为地图的最快方法是什么?我知道我们可以遍历它们。但是,这里有实用程序吗? 问题答案: 比这快吗?