使用Golang将包含结构的映射作为值导出到csv

时间:2019-03-03 01:33:41

标签: dictionary go struct export-to-csv

我有一个地图,其中有一个结构作为值,如下所示:

s = string, x = left, y = right
convert s to array
for (x times)
  q = first element in array
  remove first element from array
  add q to end of array

for (y times)
  q = last element in array
  remove last element from array
  add q to the beginning of the array

make s string again
return s

一旦我在这张地图上填充了一些记录,我就尝试使用以下命令将它们导出为csv:

type Record struct {
    ID   int
    Type string
    Year string
}

m := make(map[int]Record)

我收到错误file, err := os.Create("export.csv") checkError("Error:", err) defer file.Close() writer := csv.NewWriter(file) defer writer.Flush() for key, value := range m { r := make([]string, 0, 1+len(value)) r = append(r, key) r = append(r, value) } writer.Flush() 。我应该如何处理这里的结构?我必须以某种方式将其转换为字符串吗?

3 个答案:

答案 0 :(得分:1)

您的代码有几个问题。尝试这样的事情:

package main

import (
    "encoding/csv"
    "os"
    "strconv"
)

func main() {
    type Record struct {
        ID   int
        Type string
        Year string
    }

    m := make(map[int]Record)
    r := Record{ID: 1, Type: "A", Year: "2019"}
    m[r.ID] = r

    f, err := os.Create("export.csv")
    if err != nil {
        // handle error
    }
    defer f.Close()
    w := csv.NewWriter(f)
    defer w.Flush()

    for _, v := range m {
        r := make([]string, 0, 3)
        r = append(r, strconv.Itoa(v.ID))
        r = append(r, v.Type)
        r = append(r, v.Year)
        err := w.Write(r)
        if err != nil {
            // handle error
        }
    }
}

输出:

$ go run export.go
$ cat export.csv
1,A,2019
$ 

答案 1 :(得分:1)

这里有几个问题:

  1. writer.Write接受类型为[]string的参数,因此尝试将除字符串以外的任何内容附加到r(我认为是 record 的简写形式)无效。
  2. 您无法获得结构的长度。有关可传递给len的类型的更多信息,请参见builtin文档。

我对您的代码进行了一些修改:

  • 为csv提供标题以简化可读性
  • 更新r以接受len(headers)的容量,等于4-我不确定您想要的容量是多少,但是您可以轻松地将其更新为(可能是3,而不是4)。
  • 将ID字段转换为字符串,以便为[]string添加到writer.Write

在Go Playground中测试here

示例:

type Record struct {
    ID   int
    Type string
    Year string
}

m := make(map[int]Record)

// populate this map with some records

file, err := os.Create("export.csv")
checkError("Error:", err)
defer file.Close()
writer := csv.NewWriter(file)
defer writer.Flush()

// define column headers
headers := []string{
    "id",
    "type",
    "year",
}

// write column headers
writer.Write(headers)

var idString string

for key := range m {

    r := make([]string, 0, 1+len(headers)) // capacity of 4, 1 + the number of properties your struct has & the number of column headers you are passing

    // convert the Record.ID to a string in order to pass into []string
    idString = strconv.Itoa(m[key].ID)

    r = append(
        r,
        idString,
        m[key].Type,
        m[key].Year,
    )

    writer.Write(r)
}

答案 2 :(得分:-1)

您正在尝试在结构而非地图上应用len() 请尝试以下操作:

file, err := os.Create("export.csv")
checkError("Error:", err)
defer file.Close()
writer := csv.NewWriter(file)
defer writer.Flush()

r := make([]string, 0, 1+len(m))
for key, value := range m {
    r = append(r, key)
    r = append(r, value)
}
writer.Flush()