douwen8424 2015-09-01 09:28
浏览 89
已采纳

哪种是处理大型json并替换特定值的最佳方法?

I have a big json (30mb) which contains "title" fields in different objects , structure of json is unknown.

Known only that json contains keys "title" and string value of this key must be translated into another.

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

Replace example "alpha" -> "Α" "beta" -> "B" etc..

Which the best way achieve that in Golang , without decoding into struct ?

P.S. Json is received from network.

  • 写回答

2条回答 默认 最新

  • doubao12345 2015-09-04 01:52
    关注

    You can use a streaming JSON decoder like 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
        }
    }
    

    This should do the titleizing on the fly. The one case I can think of where it will have a problem is if you have a really really big string.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 请问有会的吗,用MATLAB做
  • ¥15 phython如何实现以下功能?查找同一用户名的消费金额合并—
  • ¥15 ARIMA模型时间序列预测用pathon解决
  • ¥15 孟德尔随机化怎样画共定位分析图
  • ¥18 模拟电路问题解答有偿速度
  • ¥15 CST仿真别人的模型结果仿真结果S参数完全不对
  • ¥15 误删注册表文件致win10无法开启
  • ¥15 请问在阿里云服务器中怎么利用数据库制作网站
  • ¥60 ESP32怎么烧录自启动程序,怎么查看客户esp32板子上程序及烧录地址
  • ¥50 html2canvas超出滚动条不显示