gpt4 book ai didi

csv - 遍历 golang 中的嵌套结构并将值存储在 slice 字符串的 slice 中

转载 作者:数据小太阳 更新时间:2023-10-29 03:03:41 24 4
gpt4 key购买 nike

我有一个嵌套结构,我需要遍历字段并将其存储在一个字符串 slice 中。然后,将其输出到 csv 文件。现在的问题是我手动访问结构中的每个字段并将其存储在 slice 接口(interface)的 slice 中,但我的实际代码有 100 个字段,因此手动调用每个字段没有意义。此外,在将 slice 接口(interface) slice 存储到 csv 时遇到问题,因为在写入输出为 [][]interface{}

的 csv 文件时出现以下错误
//      for _, value := range output {
// err := writer.Write(value) //ERROR: can't use value (type []interface{}) as type []string in argument to writer.Write (build)
// checkError("Failed write to file", err)
// }:
`can't use value (type []interface{}) as type []string in argument to writer.Write (build)`

代码:

type ApiStruct struct {
Response []struct { //100 more fields
A int `json:"a"`
B interface{} `json:"b"`
C bool `json:"c"`
D string `json:"d"`
E int `json:"e"`
F float64 `json:"f"`
G []string `json:"g"`
H bool `json:"h"`
I interface{} `json:"i"`
} `json:"response"`
}

func main() {
output := api_call()
for _, value := range output {
fmt.Println(value)
}

// write_file(output)

}

func api_call() (api_data [][]interface{}) {

api_response := `{
"response": [{
"a": 2,
"b": null,
"c": false,
"d": "sdasdas",
"e": 22,
"f": -123.2131231,
"g": ["string1", "string2"],
"h": true,
"i": null
},
{
"a": 4,
"b": null,
"c": true,
"d": "sd",
"e": 22,
"f": 1223.2131231,
"g": ["string3", "string4"],
"h": true,
"i": null
}
]
}`

var d ApiStruct
err := json.Unmarshal([]byte(api_response), &d)

if err != nil {
log.Fatal(err)
}

//instead of manually creating the headers or row lables for CSV output, want to know if there's a way to iterate through the key values in the struct
api_data = append(api_data, []interface{}{"A", "B", "C", "D", "E", "F", "G", "H", "I"})

for _, v := range d.Response {
api_data = append(api_data, []interface{}{v.A, v.B, v.C, v.D, v.E, v.F, v.G, v.H, v.I})

/*
I want to do a for loop on those fields and store values in an array like this or any other way that's easier to store in a csv file.
Instead of accessing each field individually (v.A, v.B), I want to iterate through the fields because
I have 100 fields in the struct so doesn't make sense to do v.A, etc 100 times.
Also, I am not sure if I can range over the interface slice of slice and store it in a csv file. Think it needs to be a string slice of slice [][]string.
Maybe need to convert interface slice of slice: [][]interface{} to string slice of slice: [][]string

*/

}

return
}

有关代码中的更多详细信息/注释,请参阅下面的链接:

https://play.golang.org/p/OEdi7Dfm_KL

如果有什么不清楚的地方请告诉我!感谢您的帮助!

最佳答案

您可以使用 reflect package 以编程方式处理结构的字段,特别是 TypeValue类型。例如:

type Foo struct {
A int
B bool
C string
D float64
E interface{}
}

func main() {
f := Foo{1, true, "foo", 3.45, nil}
t := reflect.TypeOf(f)
v := reflect.ValueOf(f)

for i := 0; i < v.NumField(); i++ {
fmt.Printf("OK: %q -> %#v\n", t.Field(i).Name, v.Field(i))
}
// OK: "A" -> 1
// OK: "B" -> true
// OK: "C" -> "foo"
// OK: "D" -> 3.45
// OK: "E" -> interface {}(nil)
}

使用上面演示的字段名称和值,您可以生成字符串以用于 csv package生成 CSV:

func (f Foo) ValueStrings() []string {
v := reflect.ValueOf(f)
ss := make([]string, v.NumField())
for i := range ss {
ss[i] = fmt.Sprintf("%v", v.Field(i))
}
return ss
}

func main() {
foos := []Foo{Foo{1, true, "foo", 2.34, nil}, Foo{2, false, "bar", 3.45, 1234}}
w := csv.NewWriter(os.Stdout)

// Write the CSV header.
t := reflect.TypeOf(foos[0])
names := make([]string, t.NumField())
for i := range names {
names[i] = t.Field(i).Name
}
if err := w.Write(names); err != nil {
panic(err)
}

// Write the CSV rows.
for _, foo := range foos {
if err := w.Write(foo.ValueStrings()); err != nil {
panic(err)
}
}
w.Flush()

if err := w.Error(); err != nil {
panic(err)
}
}
// A,B,C,D,E
// 1,true,foo,2.34,<nil>
// 2,false,bar,3.45,1234

关于csv - 遍历 golang 中的嵌套结构并将值存储在 slice 字符串的 slice 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48084587/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com