doupingmao1903 2017-12-12 18:35
浏览 41

将类型转换为结构的编组流

I'm currently dealing with a stream of json objects coming in to my application, and am having some difficulties figuring out what the best way of parsing them is. The stream consists of objects that have a defined type. The problem is that one of the fields in the object is of changing type. It looks like this:

[{
  "status": "closed",
  "type": "transaction",
  "transaction": {
    "TransactionType": "TypeA",
    "Account": "Some string",
    "Fee": "14",
    "date": 45325680
  },
  "validated": true
},

{
  "status": "closed",
  "type": "transaction",
  "transaction": {
    "TransactionType" : "TypeB",
    "Account" : "Some string",
    "Fee": "42",
    "Destination" : "Some string"
  },
  "validated": true
}]

You can see that the "parent" does not change, but the "transaction" does. I removed a lot of fields from the "transaction" field to make it easier to explain, but this is a type with 10-ish common fields and 10-ish changing fields that are dependent on the type. There are also 10 transaction types, this makes it pretty annoying to put everything into one struct and have a ton of optional fields. I was also thinking about one struct for every transaction type, but this does not work because then there is no way of specifying which type the field should have in the parent.

How would I parse these objects effectively? Unfortunately, I can't change the structure of the elements coming out of the stream. What would be the best way to solve this?

  • 写回答

4条回答 默认 最新

  • dousi1097 2017-12-12 19:20
    关注

    Perhaps keep your transaction as map[string]interface{}

    Example https://play.golang.com/p/j_u_ztw04M

    package main
    
    import (
        "encoding/json"
        "fmt"
    )
    
    type Stream []struct {
        Status string `json:"status"`
        Type   string `json:"type"`
    
        // map instead of struct
        Transaction map[string]interface{} `json:"transaction"`
    
        Validated bool `json:"validated"`
    }
    
    func main() {
    
        stream := Stream{}
    
        err := json.Unmarshal(rawj, &stream)
        if err != nil {
            fmt.Println("error:", err)
            return
        }
    
        for i, s := range stream {
            fmt.Println("thing:", i)
            for k, v := range s.Transaction {
    
                // do manual stuff here, perhaps long switch on k and/or
                // as suggested by Cerise Limón type switch on v
                fmt.Printf("key: %s, val: %v, val type: %T
    ", k, v, v)
    
            }
            fmt.Println()
        }
    
    }
    
    var rawj = []byte(`[{
      "status": "closed",
      "type": "transaction",
      "transaction": {
        "TransactionType": "TypeA",
        "Account": "Some string",
        "Fee": "14",
        "date": 45325680
      },
      "validated": true
    },
    
    {
      "status": "closed",
      "type": "transaction",
      "transaction": {
        "TransactionType" : "TypeB",
        "Account" : "Some string",
        "Fee": "42",
        "Destination" : "Some string"
      },
      "validated": true
    }]`)
    

    Have fun!

    评论

报告相同问题?

悬赏问题

  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程