json - 哪个是处理大 json 和替换特定值的最佳方法?

标签 json go

我有一个很大的 json (30mb),其中包含不同对象中的“标题”字段,json 的结构未知。

只知道 json 包含键“title”,这个键的字符串值必须转换成另一个。

{
    "data1" : {
        "title" : "alpha",
        "color" : "green"
    },
    "data2" : {
        "someInnerData1" : {
            "title" : "beta"
            "color" : "red"
        },
        "someInnerData2" : {
            "someArray" : [
            {
                "title" : "gamme",
                "color" : "orange"
            },
            {
                "title" : "delta",
                "color" : "purple"
            }
            ],
            "title" : "epsilon"
        }
    }
}

替换示例 “α”->“α” “测试版”->“B” 等..

在不解码为结构的情况下,在 Golang 中实现该目标的最佳方法是什么?

P.S. Json是从网络接收的。

最佳答案

您可以使用流式 JSON 解码器,例如 megajson :

// Transform 'title' strings into Title case
func TitleizeJSON(r io.Reader, w io.Writer) error {
    buf := new(bytes.Buffer)
    r = io.TeeReader(r, buf)

    s := scanner.NewScanner(r)
    var prevTok int
    var prevPos int
    wasTitle := false
    titleField := []byte("title")
    for {
        // read the next json token
        tok, data, err := s.Scan()
        if err == io.EOF {
            return nil
        } else if err != nil {
            return err
        }
        // calculate the position in the buffer
        pos := s.Pos()
        off := pos - prevPos

        switch tok {
        // if this is a string
        case scanner.TSTRING:
            // if the previous string before a : was 'title', then
            // titlelize it
            if prevTok == scanner.TCOLON && wasTitle {
                // grab the first part of the buffer and skip
                // the first ", the titleize the rest
                data = buf.Bytes()[:off][1:]
                copy(data, bytes.Title(data))
                wasTitle = false
            } else {
                wasTitle = bytes.Equal(data, titleField)
            }
        }

        // now send the data to the writer
        data = buf.Bytes()
        _, err = w.Write(data[:off])
        if err != nil {
            return err
        }

        // reset the buffer (so it doesn't grow forever)
        nbuf := make([]byte, len(data)-off)
        copy(nbuf, data[off:])
        buf.Reset()
        buf.Write(nbuf)

        // for the next go-around
        prevTok = tok
        prevPos = pos
    }
}

这应该可以即时进行标题化。我能想到的一种情况是,如果你有一个非常非常大的字符串。

关于json - 哪个是处理大 json 和替换特定值的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32328030/

相关文章:

json - 如何在Elasticsearch中通过两个子句过滤数据?

json - 如何解析带有注释的 JSON?

json - 获取一个 JSON 字符串,将其解码为 map[string]interface{},编辑并将其编码为 []byte 似乎比应该的更复杂

go - 基准测试仅显示 100%

go - 解码为指针与值接收器字段

javascript - 如何从 window.fetch() 响应中获取数据?

java - OkHttp 代理设置

go - 从 net.Conn 获取 io.ByteReader

jquery - 带 jquery、json 和上一个/下一个按钮的图库。如果 json 请求返回未定义,则画廊中断

javascript - 为什么 onChange 回调中 $scope.data 的更改不会重新绘制 chart.js?