如何找出切片中的元素位置?

OCy*_*ril 96 position go slice

如何确定切片中存在的元素的位置?

我需要以下内容:

type intSlice []int

func (slice intSlice) pos(value int) int {
    for p, v := range slice {
        if (v == value) {
            return p
        }
    }
    return -1
}
Run Code Online (Sandbox Code Playgroud)

Eva*_*haw 63

对不起,这里没有通用的库函数.Go没有直接的方法来编写可以在任何切片上运行的函数.

你的功能是有效的,但是如果你用它来写它会好一点range.

如果您碰巧有一个字节切片,则有bytes.IndexByte.

  • 技术答案是:因为Go没有泛型.如果它确实(并且可能在未来的某个时候它将拥有它们),您可以编写一个通用的IndexInSlice,它适用于任何实现==的类型.把我的Go倡导者帽子:这是关于平均经验.你不能指望单一语言在每个方面都能击败所有其他语言.Go*比C,C++,甚至Java或C#更高效,并且接近python.它是程序员生产力和本机代码生成(即速度)的结合,使其具有吸引力. (9认同)
  • 我同意埃文.附加评论:返回一个int更为惯用,其中-1表示"未找到"(如bytes.IndexByte) (3认同)
  • 谢谢。但是我有点不知所措:)我多次听到使用golang的人说,它设计得很好,可以提高程序员的工作效率。go程序看起来和python一样好:)那么,为什么没有一种通用的方法来执行这种通用任务呢?我的意思是,如果您想检查容器中是否有一个元素,则可以在集合中添加if元素:do_something() (2认同)

Ant*_*lin 48

你可以用惯用的方式创建泛型函数:

func SliceIndex(limit int, predicate func(i int) bool) int {
    for i := 0; i < limit; i++ {
        if predicate(i) {
            return i
        }
    }
    return -1
}
Run Code Online (Sandbox Code Playgroud)

用法:

xs := []int{2, 4, 6, 8}
ys := []string{"C", "B", "K", "A"}
fmt.Println(
    SliceIndex(len(xs), func(i int) bool { return xs[i] == 5 }),
    SliceIndex(len(xs), func(i int) bool { return xs[i] == 6 }),
    SliceIndex(len(ys), func(i int) bool { return ys[i] == "Z" }),
    SliceIndex(len(ys), func(i int) bool { return ys[i] == "A" }))
Run Code Online (Sandbox Code Playgroud)

  • go中的Buildtin索引函数总是返回-1.这是预期的惯用行为.缺少元素不是错误. (7认同)
  • 我不认为错误返回“-1”是惯用的,它应该使用多个返回。(我是 golang 新手,但这就是我读过的内容) (2认同)

Pod*_*.io 10

你可以写一个函数;

func indexOf(element string, data []string) (int) {
   for k, v := range data {
       if element == v {
           return k
       }
   }
   return -1    //not found.
}
Run Code Online (Sandbox Code Playgroud)

如果匹配元素,则返回字符/字符串的索引.如果未找到,则返回-1.


Lev*_*lho 9

Go 从 1.18 版本开始支持泛型,它允许您创建像您这样的函数,如下所示:

func IndexOf[T comparable](collection []T, el T) int {
    for i, x := range collection {
        if x == el {
            return i
        }
    }
    return -1
}
Run Code Online (Sandbox Code Playgroud)

如果您希望能够调用IndexOf您的收藏,您也可以使用评论中的 @mh-cbon 技术。


Mor*_*sko 7

从 Go 1.18 开始,您还可以使用https://pkg.go.dev/golang.org/x/exp/slices中的实验性通用切片包,如下所示:

package main

import "golang.org/x/exp/slices"

func main() {
    s := []int{1,2,3,4,5}
    wanted := 3
    idx := slices.Index(s, wanted)
    fmt.Printf("the index of %v is %v", wanted, idx)
}
Run Code Online (Sandbox Code Playgroud)

-1如果wanted不在切片中,它将返回。在操场上测试一下。

这是我更喜欢的方式,因为有一天它可能会成为标准库的一部分。


ale*_*dro 6

没有库函数.你必须自己编写代码.


小智 6

在 Go 1.21 及更高版本中使用slices.Index

haystack := []string{"foo", "bar", "quux"}
fmt.Println(slices.Index(haystack, "bar")) // prints 1
fmt.Println(slices.Index(haystack, "rsc")) // prints -1
Run Code Online (Sandbox Code Playgroud)


use*_*679 5

您可以迭代切片并检查元素是否与您选择的元素匹配。

func index(slice []string, item string) int {
    for i := range slice {
        if slice[i] == item {
            return i
        }
    }
    return -1
}
Run Code Online (Sandbox Code Playgroud)