CSVファイルからGo構造にレコードを自動的に逆シリアル化/アンマーシャリングする方法の問題。
たとえば、私は持っています
type Test struct {
Name string
Surname string
Age int
}
そしてCSVファイルにはレコードが含まれています
John;Smith;42
Piter;Abel;50
レコードを読み取るために「encoding/csv」パッケージを使用してから次のようなことを行う以外に、これらのレコードを構造化するための簡単な方法はありますか?
record, _ := reader.Read()
test := Test{record[0],record[1],atoi(record[2])}
CSVレコードの構造体への自動マーシャリング(stringとintに限定)を行ったようです。これがお役に立てば幸いです。
遊び場へのリンクは次のとおりです。 http://play.golang.org/p/kwc32A5mJf
func Unmarshal(reader *csv.Reader, v interface{}) error {
record, err := reader.Read()
if err != nil {
return err
}
s := reflect.ValueOf(v).Elem()
if s.NumField() != len(record) {
return &FieldMismatch{s.NumField(), len(record)}
}
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
switch f.Type().String() {
case "string":
f.SetString(record[i])
case "int":
ival, err := strconv.ParseInt(record[i], 10, 0)
if err != nil {
return err
}
f.SetInt(ival)
default:
return &UnsupportedType{f.Type().String()}
}
}
return nil
}
誰かがこの実装を必要としている場合は、githubパッケージを作成してみます。
gocarina/gocsv があり、encoding/jsonと同じ方法でカスタム構造体を処理します。特定のタイプのカスタムマーシャラーとアンマーシャラーを作成することもできます。
例:
type Client struct {
Id string `csv:"client_id"` // .csv column headers
Name string `csv:"client_name"`
Age string `csv:"client_age"`
}
func main() {
in, err := os.Open("clients.csv")
if err != nil {
panic(err)
}
defer in.Close()
clients := []*Client{}
if err := gocsv.UnmarshalFile(in, &clients); err != nil {
panic(err)
}
for _, client := range clients {
fmt.Println("Hello, ", client.Name)
}
}
あなたはあなた自身を焼くことができます。おそらくこのようなもの:
package main
import (
"fmt"
"strconv"
"strings"
)
type Test struct {
Name string
Surname string
Age int
}
func (t Test) String() string {
return fmt.Sprintf("%s;%s;%d", t.Name, t.Surname, t.Age)
}
func (t *Test) Parse(in string) {
tmp := strings.Split(in, ";")
t.Name = tmp[0]
t.Surname = tmp[1]
t.Age, _ = strconv.Atoi(tmp[2])
}
func main() {
john := Test{"John", "Smith", 42}
fmt.Printf("john:%v\n", john)
johnString := john.String()
fmt.Printf("johnString:%s\n", johnString)
var rebornJohn Test
rebornJohn.Parse(johnString)
fmt.Printf("rebornJohn:%v\n", rebornJohn)
}