是否有类似于Go中的slice.contains(object)方法,而无需在slice中逐个搜索每个元素?
当前回答
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"
})
其他回答
如果你有一个字节切片,你可以使用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
不确定这里是否需要泛型。你只需要为你想要的行为订立契约。如果您想让自己的对象在集合中表现自己,那么在其他语言中,通过重写Equals()和GetHashCode(),您必须做的事情不亚于下面所做的事情。
type Identifiable interface{
GetIdentity() string
}
func IsIdentical(this Identifiable, that Identifiable) bool{
return (&this == &that) || (this.GetIdentity() == that.GetIdentity())
}
func contains(s []Identifiable, e Identifiable) bool {
for _, a := range s {
if IsIdentical(a,e) {
return true
}
}
return false
}
排序包提供构建块,如果你的片已经排序或你愿意排序。
input := []string{"bird", "apple", "ocean", "fork", "anchor"}
sort.Strings(input)
fmt.Println(contains(input, "apple")) // true
fmt.Println(contains(input, "grow")) // false
...
func contains(s []string, searchterm string) bool {
i := sort.SearchStrings(s, searchterm)
return i < len(s) && s[i] == searchterm
}
SearchString承诺,如果x不存在,将返回插入x的索引(它可以是len(a)),因此检查它可以揭示字符串是否包含已排序的切片。
我认为map[x]bool比map[x]struct{}更有用。
为不存在的项索引映射将返回false。所以不是_,好的:= m[X],你可以说m[X]。
这使得在表达式中嵌套包含测试变得很容易。
相比使用切片,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