【问题标题】:Converting nested JSON to csv in GO在 GO 中将嵌套的 JSON 转换为 csv
【发布时间】:2016-04-21 03:19:10
【问题描述】:

我有一个示例 json,字段名称并不重要,但嵌套值和某些字段的数据类型很重要。我知道在 go 中,您必须确保在写入 csv 时,使用 csv.Writer 时数据是字符串数据类型。我的问题是,编写嵌套值的正确方法是什么,是否有一种有效的方法可以通过遍历整个 json 来转换所有非字符串值?

`{
  "name":"Name1",
  "id": 2,
  "jobs":{
      "job1":"somejob",
      "job2":"somejob2"
   },
  "prevIds":{
      "id1": 100,
      "id2": 102
  }
}`

是示例json

【问题讨论】:

  • 你能告诉我们预期的输出吗?
  • 我真的没有预期的输出,但想看看嵌套 json 会是什么样子
  • 您已经在那里编写了嵌套的 JSON,所以我想这就是您的答案?您似乎想要“将 JSON 转换为 csv”,但这还不够描述性。您希望自己的简单示例如何看起来像 csv?

标签: json csv go


【解决方案1】:

一个工作示例如下:

package main

import (
    "encoding/csv"
    "encoding/json"
    "fmt"
    "log"
    "os"
    "strconv"
)

func decodeJson(m map[string]interface{}) []string {
    values := make([]string, 0, len(m))
    for _, v := range m {
        switch vv := v.(type) {
        case map[string]interface{}:
            for _, value := range decodeJson(vv) {
                values = append(values, value)
            }
        case string:
            values = append(values, vv)
        case float64:
            values = append(values, strconv.FormatFloat(vv, 'f', -1, 64))
        case []interface{}:
            // Arrays aren't currently handled, since you haven't indicated that we should
            // and it's non-trivial to do so.
        case bool:
            values = append(values, strconv.FormatBool(vv))
        case nil:
            values = append(values, "nil")
        }
    }
    return values
}

func main() {
    var d interface{}
    err := json.Unmarshal(exampleJSON, &d)
    if err != nil {
        log.Fatal("Failed to unmarshal")
    }
    values := decodeJson(d.(map[string]interface{}))
    fmt.Println(values)

    f, err := os.Create("outputfile.csv")
    if err != nil {
        log.Fatal("Failed to create outputfile.csv")
    }
    defer f.Close()
    w := csv.NewWriter(f)
    if err := w.Write(values); err != nil {
        log.Fatal("Failed to write to file")
    }
    w.Flush()
    if err := w.Error(); err != nil {
        log.Fatal("Failed to flush outputfile.csv")
    }
}

var exampleJSON []byte = []byte(`{
  "name":"Name1",
  "id": 2,
  "jobs":{
      "job1":"somejob",
      "job2":"somejob2"
   },
  "prevIds":{
      "id1": 100,
      "id2": 102
  }
}`)

这通过解码this goblog post 中所示的任意 JSON 来工作,然后通过以通常的方式将其转换为字符串来迭代和处理每种可能的类型。如果您遇到map[string]interface{},那么您正在递归获取下一组数据。

获得[]string 后,您可以将其传递给您的csv.Writer 以随意写出。在这种情况下,输出是

Name1,2,somejob,somejob2,100,102

【讨论】:

  • 啊,我明白了!谢谢,这是非常有用的信息!是的,我不确定如何处理嵌套对象。
猜你喜欢
  • 1970-01-01
  • 2018-01-07
  • 2020-10-28
  • 2017-10-25
  • 1970-01-01
  • 2020-04-02
  • 2018-10-27
相关资源
最近更新 更多