dongyang2229 2018-07-29 10:09
浏览 99
已采纳

从json合并两个map [string] interface {}

I have two json inputs built this way

"count: 1 result: fields"   

I would like to concatenate the fields that I find within result without using a defined structure. I have tried in many ways but most of the time the result is an error about the type Interface {} or the last map overwritten the data

I would like both the "result" and the first and second map fields to be merged within the result in output.

oracle, err := http.Get("http://XXX:8080/XXXX/"+id)
    if err != nil {
            panic(err)
    }
defer oracle.Body.Close()

mysql, err := http.Get("http://XXX:3000/XXX/"+id)
if err != nil {
        panic(err)
}
defer mysql.Body.Close()

oracleJSON, err := ioutil.ReadAll(oracle.Body)
if err != nil {
        panic(err)
}
mysqlJSON, err := ioutil.ReadAll(mysql.Body)
if err != nil {
        panic(err)
}

var oracleOUT map[string]interface{}
var mysqlOUT map[string]interface{}

json.Unmarshal(oracleJSON, &oracleOUT)
json.Unmarshal(mysqlJSON, &mysqlOUT)

a := oracleOUT["result"]
b := mysqlOUT["result"]


c.JSON(http.StatusOK, gin.H{"result": ????})

this is an example of json

{"count":1,"result":{"COD_DIPENDENTE":"00060636","MATRICOLA":"60636","COGNOME":"PIPPO"}}

If i have two json like this the result of the function it should be

`"result":{"COD_DIPENDENTE":"00060636","MATRICOLA":"60636","COGNOME":"PIPPO","COD_DIPENDENTE":"00060636","MATRICOLA":"60636","COGNOME":"PIPPO"}}` 
  • 写回答

1条回答 默认 最新

  • dongyan9838 2018-07-29 22:37
    关注

    The output you are looking for is not valid JSON. However with a small change you can output something very similar to your example that is valid JSON.

    You probably do want to use a defined structure for the portion of the input that has a known structure, so that you can extract the more abstract "result" section more easily.

    If you start at the top of the input structure using a map[string]interface{} then you'll have to do a type assertion on the "result" key. For example:

    var input map[string]interface{}
    
    err = json.Unmarshal(data, &input)
    if err != nil {
        return err
    }
    keys, ok := input["result"].(map[string]interface{})
    if !ok {
        return errors.New("wasn't the type we expected")
    }
    

    However if you used a defined structure for the top level you can do it like the following which feels much cleaner.

    type Input struct {
        Count  int                    `json:"count"`
        Result map[string]interface{} `json:"result"`
    }
    
    var input Input
    err = json.Unmarshal(data, &input)
    if err != nil {
        return err
    }
    // from here you can use input.Result directly without a type assertion
    

    To generate output that has duplicate keys, you could use an array of objects with a single key/value pair in each, then you end up with a valid JSON structure that does not overwrite keys. Here's how to do that (playground link):

    package main
    
    import (
        "encoding/json"
        "fmt"
    )
    
    type Input struct {
        Count  int                    `json:"count"`
        Result map[string]interface{} `json:"result"`
    }
    
    type Output struct {
        Count  int                      `json:"count"`
        Result []map[string]interface{} `json:"result"`
    }
    
    var inputdata = [][]byte{
        []byte(`{"count":1,"result":{"COD_DIPENDENTE":"00060636", "MATRICOLA":"60636", "COGNOME":"PIPPO"}}`),
        []byte(`{"count":1,"result":{"COD_DIPENDENTE":"00060636", "MATRICOLA":"60636", "COGNOME":"PIPPO"}}`),
    }
    
    func main() {
        inputs := make([]Input, len(inputdata))
        for i := range inputs {
            err := json.Unmarshal(inputdata[i], &inputs[i])
            if err != nil {
                panic(err)
            }
        }
    
        var out Output
        out.Count = len(inputs)
        for _, input := range inputs {
            for k, v := range input.Result {
                out.Result = append(out.Result, map[string]interface{}{k: v})
            }
        }
    
        outdata, _ := json.Marshal(out)
        fmt.Println(string(outdata))
    }
    

    Which produces output that looks like this when formatted:

    {
      "count": 2,
      "result": [
        {"MATRICOLA": "60636"},
        {"COGNOME": "PIPPO"},
        {"COD_DIPENDENTE": "00060636"},
        {"COGNOME": "PIPPO"},
        {"COD_DIPENDENTE": "00060636"},
        {"MATRICOLA": "60636"}
      ]
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序