Contains method for a slice
Go中是否有类似于
mostafa已经指出,这样的方法编写起来很简单,mkb提示您使用排序包中的二进制搜索。但是如果你要做很多这样的包含检查,你也可以考虑使用一个地图代替。
使用
不,这种方法不存在,但写起来很简单:
1 2 3 4 5 6 7 8 | func contains(s []int, e int) bool { for _, a := range s { if a == e { return true } } return false } |
如果查找是代码的重要组成部分,则可以使用映射,但映射也有成本。
如果对切片进行排序,则在
与使用
简单示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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
您可以使用reflect包在具体类型为slice的接口上迭代:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | func HasElem(s interface{}, elem interface{}) bool { arrV := reflect.ValueOf(s) if arrV.Kind() == reflect.Slice { for i := 0; i < arrV.Len(); i++ { // XXX - panics if slice element points to an unexported struct field // see https://golang.org/pkg/reflect/#Value.Interface if arrV.Index(i).Interface() == elem { return true } } } return false } |
https://play.golang.org/p/jl5ud7ycnq
不确定这里是否需要泛型。你只是需要一份合同来满足你想要的行为。如果您希望自己的对象在集合中表现出自己的行为,那么执行以下操作只需在其他语言中执行,例如,通过重写equals()和gethashcode()。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 } |
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | func Contain(target interface{}, list interface{}) (bool, int) { if reflect.TypeOf(list).Kind() == reflect.Slice || reflect.TypeOf(list).Kind() == reflect.Array { listvalue := reflect.ValueOf(list) for i := 0; i < listvalue.Len(); i++ { if target == listvalue.Index(i).Interface() { return true, i } } } if reflect.TypeOf(target).Kind() == reflect.String && reflect.TypeOf(list).Kind() == reflect.String { return strings.Contains(list.(string), target.(string)), strings.Index(list.(string), target.(string)) } return false, -1 } |
。
如果不能使用基于键的地图查找项目,可以考虑使用Goderive工具。Goderive生成一个特定于类型的contains方法实现,使代码既可读又高效。
例子;
1 2 3 4 5 6 7 8 9 | type Foo struct { Field1 string Field2 int } func Test(m Foo) bool { var allItems []Foo return deriveContainsFoo(allItems, m) } |
要生成DeriveContainsFoo方法,请执行以下操作:
- 用
go get -u github.com/awalterschulze/goderive 安装Goderive - 在工作区文件夹中运行
goderive ./...
小精灵
将为派生容器生成此方法:
1 2 3 4 5 6 7 8 | func deriveContainsFoo(list []Foo, item Foo) bool { for _, v := range list { if v == item { return true } } return false } |
。
Goderive支持许多其他有用的助手方法来在Go中应用函数式编程风格。