web-dev-qa-db-fra.com

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"?

48
aaj

Avec une simple boucle for:

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

Notez que puisque le type d'élément de la tranche est un struct (et non un pointeur), cela peut être inefficace si le type de structure est "grand", car la boucle copiera chaque élément visité dans la variable de boucle.

Il serait plus rapide d'utiliser une boucle range 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 configurations peuvent exister avec le même key, mais sinon, vous devriez break sortir de la boucle si une correspondance est trouvée (pour éviter de chercher d'autres).

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

De même, s’il s’agit d’une opération fréquente, vous devez envisager de créer une map que vous pouvez simplement indexer, 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
}
76
icza

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

12
Tarion

Vous pouvez enregistrer la structure dans une carte en faisant correspondre les composants struct 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 golang virgule ok idiome, vous pouvez tester la présence de la clé:

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

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

}
1
Pravin Mishra