Contient une méthode pour une tranche

Y a-t-il quelque chose de similaire à une slice.contains(object) dans Go sans avoir à effectuer une recherche dans chaque élément d’une tranche?

    Mostafa a déjà souligné qu’une telle méthode est sortingviale à écrire et que mkb vous a donné un indice pour utiliser la recherche binary à partir du paquet de sorting. Mais si vous faites beaucoup de contrôles, vous pourriez aussi envisager d’utiliser une carte.

    Il est sortingvial de vérifier si une clé de carte spécifique existe en utilisant la value, ok := yourmap[key] idiom. Comme la valeur ne vous intéresse pas, vous pouvez également créer une map[ssortingng]struct{} par exemple. L’utilisation d’une struct{} vide struct{} présente l’avantage de ne nécessiter aucun espace supplémentaire et le type de carte interne de Go est optimisé pour ce type de valeurs. Par conséquent, map[ssortingng] struct{} est un choix populaire pour les ensembles du monde Go.

    Non, cette méthode n’existe pas, mais est sortingviale à écrire:

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

    Vous pouvez utiliser une carte si cette recherche est une partie importante de votre code, mais les cartes ont aussi un coût.

    Si la tranche est sortingée, une recherche binary est implémentée dans le package de sort .

    Au lieu d’utiliser une slice , la map peut être une meilleure solution.

    exemple simple:

     package main import "fmt" func contains(slice []ssortingng, item ssortingng) bool { set := make(map[ssortingng]struct{}, len(slice)) for _, s := range slice { set[s] = struct{}{} } _, ok := set[item] return ok } func main() { s := []ssortingng{"a", "b"} s1 := "a" fmt.Println(contains(s, s1)) } 

    http://play.golang.org/p/CEG6cu4JTf

    Vous pouvez utiliser le package de reflection pour effectuer une itération sur une interface dont le type concret est une tranche:

     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

    Pas sûr que les génériques soient nécessaires ici, vous avez juste besoin d’un contrat pour le comportement souhaité. Faire ce qui suit n’est pas plus que ce que vous auriez à faire dans d’autres langues si vous vouliez que vos propres objects se comportent dans des collections, en remplaçant Equals () et GetHashCode () par exemple.

     type Identifiable interface{ GetIdentity() ssortingng } 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 } 

    S’il n’est pas possible d’utiliser une carte pour trouver des éléments basés sur une clé, vous pouvez envisager l’outil goderive . Goderive génère une implémentation spécifique à un type d’une méthode contains, rendant votre code à la fois lisible et efficace.

    Exemple;

     type Foo struct { Field1 ssortingng Field2 int } func Test(m Foo) bool { var allItems []Foo return deriveContainsFoo(allItems, m) } 

    Pour générer la méthode deriveContainsFoo:

    • Installer goderive avec go get -u github.com/awalterschulze/goderive
    • Exécuter goderive ./... dans le dossier de votre espace de travail

    Cette méthode sera générée pour deriveContains:

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

    Goderive prend en charge de nombreuses autres méthodes utiles pour appliquer un style de programmation fonctionnel in go.