Экспорт карты, содержащей структуру в качестве значения, в CSV с помощью Golang - PullRequest
0 голосов
/ 03 марта 2019

У меня есть карта со структурой в качестве значения, как показано ниже:

type Record struct {
    ID   int
    Type string
    Year string
}

m := make(map[int]Record)

Как только я заполняю эту карту несколькими записями, я пытаюсь экспортировать их в виде csv с помощью:

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()

Я получаю ошибку invalid argument value (type Record) for len.Как я должен обрабатывать структуру здесь?Нужно ли как-то преобразовывать его в строку?

Ответы [ 3 ]

0 голосов
/ 03 марта 2019

Здесь есть несколько проблем:

  1. writer.Write принимает аргумент типа []string, поэтому пытается добавить что-либо, кроме строки, к r (я полагаю, это сокращениепредставление запись ) не будет работать.
  2. Вы не можете получить длину структуры.См. Документацию встроенный для получения дополнительной информации о типах, которые вы можете передать в len.

Я сделал несколько изменений в вашем коде:

  • предоставляет заголовки для csv для удобства чтения
  • обновление r для принятияемкость len(headers), равно 4 - я не был уверен, что вы хотели, чтобы емкость была, но вы можете легко обновить это (вероятно, 3, а не 4).
  • преобразовать поле идентификатора в строку в порядкедобавить к []string для writer.Write

Тест здесь на Go Playground.

Пример:

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)
}
0 голосов
/ 03 марта 2019

Вы пытаетесь применить 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()
0 голосов
/ 03 марта 2019

Ваш код имеет несколько проблем.Попробуйте что-то вроде этого:

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
$ 
...