2023-11-10 05:01:49

包含片的方法

是否有类似于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"
})

其他回答

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

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)

不,这样的方法不存在,但是写起来很简单:

func contains(s []int, e int) bool {
    for _, a := range s {
        if a == e {
            return true
        }
    }
    return false
}

如果查找是代码的重要部分,则可以使用映射,但映射也有成本。

我使用reflect包创建了以下Contains函数。 此函数可用于各种类型,如int32或struct等。

// Contains returns true if an element is present in a slice
func Contains(list interface{}, elem interface{}) bool {
    listV := reflect.ValueOf(list)

    if listV.Kind() == reflect.Slice {
        for i := 0; i < listV.Len(); i++ {
            item := listV.Index(i).Interface()

            target := reflect.ValueOf(elem).Convert(reflect.TypeOf(item)).Interface()
            if ok := reflect.DeepEqual(item, target); ok {
                return true
            }
        }
    }
    return false
}

contains函数的用法如下

// slice of int32
containsInt32 := Contains([]int32{1, 2, 3, 4, 5}, 3)
fmt.Println("contains int32:", containsInt32)

// slice of float64
containsFloat64 := Contains([]float64{1.1, 2.2, 3.3, 4.4, 5.5}, 4.4)
fmt.Println("contains float64:", containsFloat64)


// slice of struct
type item struct {
    ID   string
    Name string
}
list := []item{
    item{
        ID:   "1",
        Name: "test1",
    },
    item{
        ID:   "2",
        Name: "test2",
    },
    item{
        ID:   "3",
        Name: "test3",
    },
}
target := item{
    ID:   "2",
    Name: "test2",
}
containsStruct := Contains(list, target)
fmt.Println("contains struct:", containsStruct)

// Output:
// contains int32: true
// contains float64: true
// contains struct: true

详情请点击此处: https://github.com/glassonion1/xgo/blob/main/contains.go

如果切片已排序,则排序包中实现了二进制搜索。

这可能会被认为有点“粗糙”,但根据切片的大小和内容,您可以将切片连接在一起并进行字符串搜索。

例如,您有一个包含单个单词值的切片(例如:“是”,“不是”,“可能”)。这些结果被追加到一个片中。如果您想检查此片是否包含任何“可能”结果,您可以使用

exSlice := ["yes", "no", "yes", "maybe"]
if strings.Contains(strings.Join(exSlice, ","), "maybe") {
  fmt.Println("We have a maybe!")
}

这是否合适取决于切片的大小和成员的长度。对于较大的切片或较长的值,可能存在性能或适用性问题,但对于较小的有限大小的切片和简单的值,这是实现所需结果的有效一行程序。