Как искать элемент в куске голанга
У меня есть кусочек структур.
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"
?
Ответы
Ответ 1
С помощью простого цикла 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
}
Ответ 2
Вы можете использовать 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)
}
}
См. Https://play.golang.org/p/47OPrjKb0g_c
Ответ 3
Вы можете сохранить структуру в карте, сопоставляя компоненты struct Key
и Value
с их фиктивными ключами и значениями на карте:
mapConfig := map[string]string{}
for _, v := range myconfig {
mapConfig[v.Key] = v.Value
}
Затем, используя идиому golang comma ok, вы можете проверить наличие ключа:
if v, ok := mapConfig["key1"]; ok {
fmt.Printf("%s exists", v)
}
Ответ 4
Для этого нет никакой библиотечной функции. Вы должны сделать код самостоятельно.
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)
}
}
}