2023-11-10 05:01:49

包含片的方法

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

其他回答

如果使用地图根据钥匙查找物品是不可行的,你可以考虑使用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中应用函数式编程风格。

如果你有一个字节切片,你可以使用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

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

从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兼容性承诺™,并且在正式添加到标准库之前可能会更改。

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

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

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

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