英文:
Using "dynamic" key to extract value from map
问题
来自JavaScript背景,刚开始学习Golang。我正在学习Golang中的所有新术语,并创建新的问题,因为我找不到所需的答案(可能是因为对要搜索的术语了解不足)。
我创建了一个自定义类型,创建了一个类型的数组,并且我想创建一个函数,可以检索特定键的所有值,并返回所有值的数组(在此示例中为品牌)。
type Car struct {
brand string
units int
}
....
var cars []Car
var singleCar Car
//所以我在这里有一个循环,并在for循环内创建许多单个汽车
singleCar = Car {
brand: "Mercedes",
units: 20
}
//然后我将singleCar附加到cars中
cars = append(cars, singleCar)
现在我想创建一个函数,可以检索所有品牌,并尝试以下操作。我打算将key
作为动态值,以便可以按特定键搜索,例如品牌、型号、容量等。
func getUniqueByKey(v []Car, key string) []string {
var combined []string
for i := range v {
combined = append(combined, v[i].brand)
//这一行返回错误 -
//invalid operation: cannot index v[i] (map index expression of type Car)compilerNonIndexableOperand
}
return combined
//这应该返回["Mercedes", "Honda", "Ferrari"]
}
上述函数应该在我使用getUniqueByKey(cars, "brand")
时起作用,在此示例中,brand是key
。但是我不知道语法,所以它返回错误。
英文:
Came from javascript background, and just started with Golang. I am learning all the new terms in Golang, and creating new question because I cannot find the answer I need (probably due to lack of knowledge of terms to search for)
I created a custom type, created an array of types, and I want to create a function where I can retrieve all the values of a specific key, and return an array of all the values (brands in this example)
type Car struct {
brand string
units int
}
....
var cars []Car
var singleCar Car
//So i have a loop here and inside the for-loop, i create many single cars
singleCar = Car {
brand: "Mercedes",
units: 20
}
//and i append the singleCar into cars
cars = append(cars, singleCar)
Now what I want to do is to create a function that I can retrieve all the brands, and I tried doing the following. I intend to have key
as a dynamic value, so I can search by specific key, e.g. brand, model, capacity etc.
func getUniqueByKey(v []Car, key string) []string {
var combined []string
for i := range v {
combined = append(combined, v[i][key])
//this line returns error -
//invalid operation: cannot index v[i] (map index expression of type Car)compilerNonIndexableOperand
}
return combined
//This is suppose to return ["Mercedes", "Honda", "Ferrari"]
}
The above function is suppose to work if i use getUniqueByKey(cars, "brand")
where in this example, brand is the key
. But I do not know the syntaxes so it's returning error.
答案1
得分: 1
似乎你正在尝试使用切片访问器来获取属性,但在Go语言中这是行不通的。你需要为每个属性编写一个函数。以下是一个使用品牌属性的示例:
func getUniqueBrands(v []Car) []string {
var combined []string
tempMap := make(map[string]bool)
for _, c := range v {
if _, p := tempMap[c.brand]; !p {
tempMap[c.brand] = true
combined = append(combined, c.brand)
}
}
return combined
}
另外,请注意在这里使用的for循环来获取Car的值。Go语言的range
可以用于仅迭代索引或同时迭代索引和值。通过将值赋给_
来丢弃索引。
**我建议在这段代码中添加一个switch-case块来获取你想要的结果。**如果需要返回多个类型,请使用interface{}
和类型断言。
英文:
Seems like you're trying to get a property using a slice accessor, which doesn't work in Go. You'd need to write a function for each property. Here's an example with the brands:
func getUniqueBrands(v []Car) []string {
var combined []string
tempMap := make(map[string]bool)
for _, c := range v {
if _, p := tempMap[c.brand]; !p {
tempMap[c.brand] = true
combined = append(combined, c.brand)
}
}
return combined
}
Also, note the for loop being used to get the value of Car here. Go's range
can be used to iterate over just indices or both indices and values. The index is discarded by assigning to _
.
I would recommend re-using this code with an added switch-case block to get the result you want. If you need to return multiple types, use interface{}
and type assertion.
答案2
得分: 0
也许你可以将你的结构体编组成JSON数据,然后将其转换为map。以下是示例代码:
package main
import (
"encoding/json"
"fmt"
)
type RandomStruct struct {
FieldA string
FieldB int
FieldC string
RandomFieldD bool
RandomFieldE interface{}
}
func main() {
fieldName := "FieldC"
randomStruct := RandomStruct{
FieldA: "a",
FieldB: 5,
FieldC: "c",
RandomFieldD: false,
RandomFieldE: map[string]string{"innerFieldA": "??"},
}
randomStructs := make([]RandomStruct, 0)
randomStructs = append(randomStructs, randomStruct, randomStruct, randomStruct)
res := FetchRandomFieldAndConcat(randomStructs, fieldName)
fmt.Println(res)
}
func FetchRandomFieldAndConcat(randomStructs []RandomStruct, fieldName string) []interface{} {
res := make([]interface{}, 0)
for _, randomStruct := range randomStructs {
jsonData, _ := json.Marshal(randomStruct)
jsonMap := make(map[string]interface{})
err := json.Unmarshal(jsonData, &jsonMap)
if err != nil {
fmt.Println(err)
// panic(err)
}
value, exists := jsonMap[fieldName]
if exists {
res = append(res, value)
}
}
return res
}
希望对你有帮助!
英文:
Maybe you could marshal your struct into json data then convert it to a map. Example code:
package main
import (
"encoding/json"
"fmt"
)
type RandomStruct struct {
FieldA string
FieldB int
FieldC string
RandomFieldD bool
RandomFieldE interface{}
}
func main() {
fieldName := "FieldC"
randomStruct := RandomStruct{
FieldA: "a",
FieldB: 5,
FieldC: "c",
RandomFieldD: false,
RandomFieldE: map[string]string{"innerFieldA": "??"},
}
randomStructs := make([]RandomStruct, 0)
randomStructs = append(randomStructs, randomStruct, randomStruct, randomStruct)
res := FetchRandomFieldAndConcat(randomStructs, fieldName)
fmt.Println(res)
}
func FetchRandomFieldAndConcat(randomStructs []RandomStruct, fieldName string) []interface{} {
res := make([]interface{}, 0)
for _, randomStruct := range randomStructs {
jsonData, _ := json.Marshal(randomStruct)
jsonMap := make(map[string]interface{})
err := json.Unmarshal(jsonData, &jsonMap)
if err != nil {
fmt.Println(err)
// panic(err)
}
value, exists := jsonMap[fieldName]
if exists {
res = append(res, value)
}
}
return res
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论