109 votes

Comment rechercher un élément dans une tranche de golang

J'ai une tranche de structs.

 type Config struct {
    Key string
    Value string
}

// I form a slice of the above struct
var myconfig []Config 

// unmarshal a response body into the above slice
if err := json.Unmarshal(respbody, &myconfig); err != nil {
    panic(err)
}

fmt.Println(config)
 

Voici le résultat de ceci:

 [{key1 test} {web/key1 test2}]
 

Comment puis-je rechercher ce tableau pour obtenir l'élément où key="key1" ?

174voto

icza Points 3857

Avec un simple for boucle:

for _, v := range myconfig {
    if v.Key == "key1" {
        // Found!
    }
}

Noter que, depuis le type d'élément de la tranche est un struct (et non pas un pointeur), cela peut être inefficace si la structure est de type "big" que la boucle de copie visité chaque élément dans la variable de boucle.

Il serait plus rapide d'utiliser un range boucle juste sur l'index, cela évite de copier les éléments:

for i := range myconfig {
    if myconfig[i].Key == "key1" {
        // Found!
    }
}

Notes:

Cela dépend de votre cas si plusieurs configs peuvent exister avec le même key, mais si non, vous devriez break hors de la boucle si une correspondance est trouvée (afin d'éviter de chercher pour les autres).

for i := range myconfig {
    if myconfig[i].Key == "key1" {
        // Found!
        break
    }
}

Aussi, si c'est fréquent, vous devez envisager la construction d'un map de ce que vous pouvez tout simplement l'index, par exemple

// Build a config map:
confMap := map[string]string{}
for _, v := range myconfig {
    confMap[v.Key] = v.Value
}

// And then to find values by key:
if v, ok := confMap["key1"]; ok {
    // Found
}

30voto

Tarion Points 1867

Vous pouvez utiliser sort.Slice() plus sort.Search()

 type Person struct {
    Name string
}

func main() {
    crowd := []Person{{"Zoey"}, {"Anna"}, {"Benni"}, {"Chris"}}

    sort.Slice(crowd, func(i, j int) bool {
        return crowd[i].Name <= crowd[j].Name
    })

    needle := "Benni"
    idx := sort.Search(len(crowd), func(i int) bool {
        return string(crowd[i].Name) >= needle
    })

    if crowd[idx].Name == needle {
        fmt.Println("Found:", idx, crowd[idx])
    } else {
        fmt.Println("Found noting: ", idx)
    }
}
 

Voir: https://play.golang.org/p/47OPrjKb0g_c

10voto

Simo Endre Points 2569

Vous pouvez enregistrer la structure dans une carte en faisant correspondre les composants structure Key et Value à leurs parties fictives de clé et de valeur sur la carte:

 mapConfig := map[string]string{}
for _, v := range myconfig {
   mapConfig[v.Key] = v.Value
}
 

Ensuite, en utilisant le langage golang comma ok, vous pouvez tester la présence de la clé:

 if v, ok := mapConfig["key1"]; ok {
    fmt.Printf("%s exists", v)
}   
 

4voto

Pravin Mishra Points 2544

Il n'y a pas de fonction de bibliothèque pour cela. Vous devez coder vous-même.

 for _, value := range myconfig {
    if value .Key == "key1" {
        // logic
    }
}
 

Code de travail: https://play.golang.org/p/IJIhYWROP_

 package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    type Config struct {
        Key   string
        Value string
    }

    var respbody = []byte(`[
        {"Key":"Key1", "Value":"Value1"},
        {"Key":"Key2", "Value":"Value2"}
    ]`)

    var myconfig []Config

    err := json.Unmarshal(respbody, &myconfig)
    if err != nil {
        fmt.Println("error:", err)
    }

    fmt.Printf("%+v\n", myconfig)

    for _, v := range myconfig {
        if v.Key == "Key1" {
            fmt.Println("Value: ", v.Value)
        }
    }

}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X