2023-11-10 05:01:49

包含片的方法

是否有类似于Go中的slice.contains(object)方法,而无需在slice中逐个搜索每个元素?


当前回答

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
}

其他回答

如果使用地图根据钥匙查找物品是不可行的,你可以考虑使用goderived工具。goderived生成包含方法的特定于类型的实现,使您的代码既可读又高效。

例子;

type Foo struct {
    Field1 string
    Field2 int
} 

func Test(m Foo) bool {
     var allItems []Foo
     return deriveContainsFoo(allItems, m)
}

生成派生econtainsfoo方法:

使用go get -u github.com/awalterschulze/goderive安装goderived 运行goderived。/…在工作区文件夹中

这个方法将为衍生的包含生成:

func deriveContainsFoo(list []Foo, item Foo) bool {
    for _, v := range list {
        if v == item {
            return true
        }
    }
    return false
}

goderived还支持很多其他有用的辅助方法,可以在go中应用函数式编程风格。

有几个软件包可以提供帮助,但这一个似乎很有前途:

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)

我认为map[x]bool比map[x]struct{}更有用。

为不存在的项索引映射将返回false。所以不是_,好的:= m[X],你可以说m[X]。

这使得在表达式中嵌套包含测试变得很容易。

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"
})

Mostafa已经指出,编写这样的方法很简单,mkb提示您使用排序包中的二进制搜索。但是如果您要做很多这样的包含检查,您也可以考虑使用地图代替。

通过使用value (ok:= yourmap[key]习语)来检查特定的映射键是否存在是很简单的。因为你对这个值不感兴趣,你也可以创建一个map[string]struct{}。在这里使用空结构体{}的好处是它不需要任何额外的空间,Go的内部映射类型针对这种值进行了优化。因此,map[string] struct{}是Go世界中集合的流行选择。