是否有类似于Go中的slice.contains(object)方法,而无需在slice中逐个搜索每个元素?
当前回答
如果你有一个字节切片,你可以使用bytes包:
package main
import "bytes"
func contains(b []byte, sub byte) bool {
return bytes.Contains(b, []byte{sub})
}
func main() {
b := contains([]byte{10, 11, 12, 13, 14}, 13)
println(b)
}
或suffixarray包:
package main
import "index/suffixarray"
func contains(b []byte, sub byte) bool {
return suffixarray.New(b).Lookup([]byte{sub}, 1) != nil
}
func main() {
b := contains([]byte{10, 11, 12, 13, 14}, 13)
println(b)
}
如果你有一个int片,你可以使用intsets包:
package main
import "golang.org/x/tools/container/intsets"
func main() {
var s intsets.Sparse
for n := 10; n < 20; n++ {
s.Insert(n)
}
b := s.Has(16)
println(b)
}
https://golang.org/pkg/bytes https://golang.org/pkg/index/suffixarray https://pkg.go.dev/golang.org/x/tools/container/intsets
其他回答
有几个软件包可以提供帮助,但这一个似乎很有前途:
https://github.com/wesovilabs/koazee
var numbers = []int{1, 5, 4, 3, 2, 7, 1, 8, 2, 3}
contains, _ := stream.Contains(7)
fmt.Printf("stream.Contains(7): %v\n", contains)
Mostafa已经指出,编写这样的方法很简单,mkb提示您使用排序包中的二进制搜索。但是如果您要做很多这样的包含检查,您也可以考虑使用地图代替。
通过使用value (ok:= yourmap[key]习语)来检查特定的映射键是否存在是很简单的。因为你对这个值不感兴趣,你也可以创建一个map[string]struct{}。在这里使用空结构体{}的好处是它不需要任何额外的空间,Go的内部映射类型针对这种值进行了优化。因此,map[string] struct{}是Go世界中集合的流行选择。
go样式:
func Contains(n int, match func(i int) bool) bool {
for i := 0; i < n; i++ {
if match(i) {
return true
}
}
return false
}
s := []string{"a", "b", "c", "o"}
// test if s contains "o"
ok := Contains(len(s), func(i int) bool {
return s[i] == "o"
})
相比使用切片,map可能是更好的解决方案。
简单的例子:
package main
import "fmt"
func contains(slice []string, item string) bool {
set := make(map[string]struct{}, len(slice))
for _, s := range slice {
set[s] = struct{}{}
}
_, ok := set[item]
return ok
}
func main() {
s := []string{"a", "b"}
s1 := "a"
fmt.Println(contains(s, s1))
}
http://play.golang.org/p/CEG6cu4JTf
从Go 1.18开始,你可以使用slices包——特别是泛型Contains函数: https://pkg.go.dev/golang.org/x/exp/slices。
go get golang.org/x/exp/slices
import "golang.org/x/exp/slices"
things := []string{"foo", "bar", "baz"}
slices.Contains(things, "foo") // true
请注意,由于这是在标准库之外的一个实验包,所以它不绑定到Go 1兼容性承诺™,并且在正式添加到标准库之前可能会更改。