webentwicklung-frage-antwort-db.com.de

So suchen Sie nach einem Element in einem Golang-Slice

Ich habe ein Stück Strukturen.

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)

Hier ist die Ausgabe davon:

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

Wie kann ich dieses Array durchsuchen, um das Element zu erhalten, in dem key="key1"?

48
aaj

Mit einer einfachen for Schleife:

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

Da der Elementtyp des Slice ein struct (kein Zeiger) ist, kann dies ineffizient sein, wenn der Strukturtyp "groß" ist, da die Schleife jedes besuchte Element in die Schleifenvariable kopiert.

Es wäre schneller, eine range -Schleife nur für den Index zu verwenden. Auf diese Weise wird vermieden, dass die Elemente kopiert werden:

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

Anmerkungen:

Es hängt von Ihrem Fall ab, ob mehrere Konfigurationen mit demselben key existieren. Wenn dies nicht der Fall ist, sollten Sie break aus der Schleife aussteigen, wenn eine Übereinstimmung gefunden wird (um die Suche nach anderen zu vermeiden).

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

Auch wenn dies eine häufige Operation ist, sollten Sie erwägen, daraus ein map zu erstellen, das Sie einfach indizieren können, z.

// 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

Sie können sort.Slice() plus sort.Search() verwenden

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

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

12
Tarion

Sie können die Struktur in einer Map speichern, indem Sie die Komponenten struct Key und Value mit ihren fiktiven Schlüssel- und Werteteilen auf der Map abgleichen:

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

Dann können Sie mit dem golang Komma ok idiom die Schlüsselpräsenz testen:

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

Dafür gibt es keine Bibliotheksfunktion. Sie müssen selbst codieren.

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

Arbeitscode: 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