2016-07-29 13 views
14

Ich habe ein Stück Struktur.Wie suche ich nach einem Element in einem Golang Slice

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) 

Here is the output of this 
[{key1 test} {web/key1 test2}] 

Wie ich dieses Array suchen kann das Element, in dem key="key1" zu bekommen?

+0

Wie Ihre Config-Struktur wie eine einfache Karte sieht ich darauf hinweisen möchte, dass Sie alle JSON-Daten zu einem 'Karte entschlüsseln kann [string] Schnittstelle {}'. Wenn Sie interessiert sind, gehen Sie [diesen offiziellen Blog-Post] (https://blog.golang.org/json-and-go) – tsabsch

Antwort

25

Mit einem einfachen for loop:

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

anzumerken, dass, da Elementtyp der Scheibe ein struct ist (kein Zeiger), dies ineffizient sein, wenn der Strukturtyp „big“, wie die Schleife wird Kopieren Sie jedes besuchte Element in die Schleifenvariable.

Es würde schneller sein, eine range Schleife verwenden nur auf dem Index, vermeidet dies die Elemente Kopieren:

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

Hinweise:

Es auf Ihrem Fall davon ab, ob mehrere Konfigurationen mit existieren das gleiche key, aber wenn nicht, sollten Sie break außerhalb der Schleife, 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 eine map von Gebäude es betrachten, die kann man einfach Index, zum Beispiel

// 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 
} 
+0

Danke, ich bin auch frei, Zeiger zu verwenden. Denkst du, hier wäre ein Zeiger auf struct schneller? Können wir eine Reihe von Zeigern haben? – aaj

+0

@ love2code Ja, Sie können auch einen Zeigerbereich verwenden, oder wenn Sie die Indizes überlappen (wie in meinem zweiten Beispiel), werden die Werte nicht kopiert. Wie du willst. – icza

+0

ok Ich habe 'var myconfig [] * Config' erstellt und den ersten Ansatz verwendet. Ich hoffe, dies ist die beste Option Leistung weise – aaj

2

Sie haben die Struktur in eine Karte durch Anpassung der Struktur Key und Value Komponenten auf ihre fiktiven Schlüssel und Wert Teile auf der Karte speichern:

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

Dann mit dem golang Komma ok Idiom Sie können für den Schlüssel Präsenz testen:

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

Es gibt keine Bibliotheksfunktion dafür. Sie müssen selbst programmieren.

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

} 
Verwandte Themen