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 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行