drjmrg8766 2018-11-29 13:21
浏览 27

将复杂的JSON解组为结构并访问数据(slice of slices)

I've been bashing my head about this for a while now. I have a JSON file that must be in the following format that I need to iterate through and use IF statements on in Go:

[
[
    {
        "configName": "customer"
    },
    {
        "config": [
            {
                "emailSubject": "New customer added"
            },
            {
                "text": "Hi test 2"
            },
            {
                "text": "added 2"
            }
        ]
    }
]
[
    {
        "configName": "customerAndUser"
    },
    {
        "config": [
            {
                "emailSubject": "New customer added"
            },
            {
                "text": "Hi, test 1"
            },
            {
                "text": "added 1"
            }
        ]
    }
]
]

And I want to put it into a struct, like this:

type Config [][]struct {
    configName string `json: configName`
    config     []struct {
        Text         string `json: text`
        EmailSubject string `json: emailSubject`
    } `json: config`
}

I can unmarshal the data fine, like this:

configData, err := ioutil.ReadFile("testing-config.json")
if err != nil {
    fmt.Println(err)
}
var configDataUnmarshalled Config

json.Unmarshal([]byte(configData), &configDataUnmarshalled)

And then the data prints, sort of okay, but here is where things get a little strange: the print statement is returning blanks for the items that I do not specify to print. Here is a sample of what's printed when I print the unmarshalled data:

Print output from unmarshalled data:

[[{customer []} { [{ New customer added} {hi test 2 } {added 2 }]}] [{customerAndUser []} { [{ New customer added} {hi test 1 } {added 1 }]}]]

But then I can't seem to use IF statements or loop over the elements in the config key!

IF statement being ignored in the for loop (see output below code)

for _, configs := range configDataUnmarshalled {

    for _, configurations := range configs {

        fmt.Println("These are the top level elements in my struct: ", configurations.ConfigName)

        if configurations.ConfigName == "customerAndUser" {

            for _, config := range configurations.Config {

                fmt.Println(config)
            }
        }
    }
}

This is what is printed:

These are the top level elements in my struct:  customer
These are the top level elements in my struct:
These are the top level elements in my struct:  customerAndUser
These are the top level elements in my struct:

From the FOR loop you can see that I want to access the data when a config is of a certain name, in this case "customerAndUser"

Here the IF statement is being ignored completely

I have two things I want to understand/solve:

  1. How can I access the data following an IF statement
  2. Why is the program printing blanks?

Desired output would be printing out the emailSubject, and the two Text element's data to the console for the config with name customerAndUser

What should be printed:

New customer added
hi test 1
added 1

Thanks for your help

  • 写回答

1条回答 默认 最新

  • duannengling4705 2018-11-29 13:49
    关注

    json config is very smell. The struct contain configName and config is two separately structs in a slice. configName have value so config is empty and backwards. This will work when json like this.

    {
            "configName": "customerAndUser",
            "config": [
                {
                    "emailSubject": "New customer added"
                },
                {
                    "text": "Hi, test 1"
                },
                {
                    "text": "added 1"
                }
            ]
     }
    

    So if you can't change json config format. This is solution

    endUser := false
    
    for _, configs := range configDataUnmarshalled {
    
        endUser = false
        for _, configurations := range configs {
    
            if configurations.ConfigName == "customerAndUser" {
                endUser = true
                continue
            }
    
            if !endUser || len(configurations.Config) == 0 {
                continue
            }
    
            for _, config := range configurations.Config {
                fmt.Println(config)
            }
        }
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 ogg dd trandata 报错
  • ¥15 高缺失率数据如何选择填充方式
  • ¥50 potsgresql15备份问题
  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错