如何在 golang 切片中搜索元素

新手上路,请多包涵

我有一片结构。

 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}]

我如何搜索此数组以获取元素 where key="key1"

原文由 codec 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

从添加泛型支持的 Go 1.18 开始,有一个 golang.org/x/exp/slices 包,其中包含一个名为 slices.IndexFunc() 的通用“查找”函数:

>  func IndexFunc[E any](s []E, f func(E) bool) int
>
> ```
>
> IndexFunc 返回满足 f(s\[i\]) 的第一个索引 i,如果不满足则返回 -1。

使用那个:

idx := slices.IndexFunc(myconfig, func(c Config) bool { return c.Key == “key1” })


在 [Go Playground](https://go.dev/play/p/OozTY5WlDqw) 上尝试一下。

在 Go 1.18 之前和更快的替代方案,请继续阅读:

使用一个简单的 `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 }

”`

原文由 icza 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以使用 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 idx < len(crowd) && crowd[idx].Name == needle {
        fmt.Println("Found:", idx, crowd[idx])
    } else {
        fmt.Println("Found noting: ", idx)
    }
}

请参阅:https: //play.golang.org/p/47OPrjKb0g_c

原文由 Tarion 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题