我有一块结构。
type Config struct {
Key string
Value string
}
// I form a slice of the above struct
var myconfig []Config
// unmarshal a response body into the above slice
if err := json.Unmarshal(respbody, &myconfig); err != nil {
panic(err)
}
fmt.Println(config)
以下是此输出:
[{key1 test} {web/key1 test2}]
如何搜索此数组以获取key="key1"
?
答案 0 :(得分:69)
使用简单的for
循环:
for _, v := range myconfig {
if v.Key == "key1" {
// Found!
}
}
注意,由于切片的元素类型是struct
(不是指针),如果结构类型是"大"这可能是低效的。因为循环会将每个访问过的元素复制到循环变量中。
在索引上使用range
循环会更快,这样可以避免复制元素:
for i := range myconfig {
if myconfig[i].Key == "key1" {
// Found!
}
}
备注:强>
根据您的情况,是否可能存在具有相同key
的多个配置,但如果不存在,则如果找到匹配则应break
离开循环(以避免搜索其他配置)。
for i := range myconfig {
if myconfig[i].Key == "key1" {
// Found!
break
}
}
此外,如果这是一个频繁的操作,你应该考虑从中构建一个map
,你可以简单地索引,例如。
// Build a config map:
confMap := map[string]string{}
for _, v := range myconfig {
confMap[v.Key] = v.Value
}
// And then to find values by key:
if v, ok := confMap["key1"]; ok {
// Found
}
答案 1 :(得分:9)
您可以使用sort.Slice()
加sort.Search()
type Person struct {
Name string
}
func main() {
crowd := []Person{{"Zoey"}, {"Anna"}, {"Benni"}, {"Chris"}}
sort.Slice(crowd, func(i, j int) bool {
return crowd[i].Name <= crowd[j].Name
})
needle := "Benni"
idx := sort.Search(len(crowd), func(i int) bool {
return string(crowd[i].Name) >= needle
})
if crowd[idx].Name == needle {
fmt.Println("Found:", idx, crowd[idx])
} else {
fmt.Println("Found noting: ", idx)
}
}
答案 2 :(得分:8)
您可以将结构Key
和Value
组件与地图上的虚拟键和值部分相匹配,从而将结构保存到地图中:
mapConfig := map[string]string{}
for _, v := range myconfig {
mapConfig[v.Key] = v.Value
}
然后使用golang 逗号确定成语,您可以测试密钥存在:
if v, ok := mapConfig["key1"]; ok {
fmt.Printf("%s exists", v)
}
答案 3 :(得分:1)
没有库功能。你必须自己编码。
for _, value := range myconfig {
if value .Key == "key1" {
// logic
}
}
工作代码:https://play.golang.org/p/IJIhYWROP_
package main
import (
"encoding/json"
"fmt"
)
func main() {
type Config struct {
Key string
Value string
}
var respbody = []byte(`[
{"Key":"Key1", "Value":"Value1"},
{"Key":"Key2", "Value":"Value2"}
]`)
var myconfig []Config
err := json.Unmarshal(respbody, &myconfig)
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%+v\n", myconfig)
for _, v := range myconfig {
if v.Key == "Key1" {
fmt.Println("Value: ", v.Value)
}
}
}
答案 4 :(得分:0)
正如其他人所评论的那样,在您可以使用匿名功能编写自己的过程来解决此问题之前。
我用两种方法解决它:
func Find(slice interface{}, f func(value interface{}) bool) int {
s := reflect.ValueOf(slice)
if s.Kind() == reflect.Slice {
for index := 0; index < s.Len(); index++ {
if f(s.Index(index).Interface()) {
return index
}
}
}
return -1
}
使用示例:
type UserInfo struct {
UserId int
}
func main() {
var (
destinationList []UserInfo
userId int = 123
)
destinationList = append(destinationList, UserInfo {
UserId : 23,
})
destinationList = append(destinationList, UserInfo {
UserId : 12,
})
idx := Find(destinationList, func(value interface{}) bool {
return value.(UserInfo).UserId == userId
})
if idx < 0 {
fmt.Println("not found")
} else {
fmt.Println(idx)
}
}
计算成本较低的第二种方法:
func Search(length int, f func(index int) bool) int {
for index := 0; index < length; index++ {
if f(index) {
return index
}
}
return -1
}
使用示例:
type UserInfo struct {
UserId int
}
func main() {
var (
destinationList []UserInfo
userId int = 123
)
destinationList = append(destinationList, UserInfo {
UserId : 23,
})
destinationList = append(destinationList, UserInfo {
UserId : 123,
})
idx := Search(len(destinationList), func(index int) bool {
return destinationList[index].UserId == userId
})
if idx < 0 {
fmt.Println("not found")
} else {
fmt.Println(idx)
}
}