Wie kann ich überprüfen, ob x
in einem Array ohne über das gesamte Array zu iterieren, mit Go vorhanden ist? Hat die Sprache dafür eine Konstruktion?
Wie in Python:
if "x" in array:
# mache etwas
Wie kann ich überprüfen, ob x
in einem Array ohne über das gesamte Array zu iterieren, mit Go vorhanden ist? Hat die Sprache dafür eine Konstruktion?
Wie in Python:
if "x" in array:
# mache etwas
Es gibt in Go keinen integrierten Operator, um dies zu tun. Sie müssen über das Array iterieren. Sie können Ihre eigene Funktion schreiben, um dies zu tun, wie folgt:
func stringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}
Oder in Go 1.18 oder neuer können Sie slices.Contains
(von golang.org/x/exp/slices) verwenden.
Wenn Sie die Mitgliedschaft überprüfen möchten, ohne über die ganze Liste zu iterieren, müssen Sie anstelle eines Arrays oder Slices eine Map verwenden, wie folgt:
visitedURL := map[string]bool {
"http://www.google.com": true,
"https://paypal.com": true,
}
if visitedURL[thisSite] {
fmt.Println("Schon hier gewesen.")
}
Dies ist ein Zitat aus dem Buch "Programming in Go: Creating Applications for the 21st Century":
Die Verwendung eines einfachen linearen Suchalgorithmus ist die einzige Option für unsortierte Daten und eignet sich gut für kleine Slices (bis zu Hunderten von Elementen). Für größere Slices ist der lineare Suchalgorithmus jedoch sehr ineffizient, da im Durchschnitt jedes Mal die Hälfte der Elemente verglichen werden müssen.
Go bietet eine sort.Search() Methode, die den binären Suchalgorithmus verwendet: Dies erfordert jedes Mal nur einen Vergleich von log2(n) Elementen (wobei n die Anzahl der Elemente ist). Zum Vergleich: Eine lineare Suche von 1000000 Elementen erfordert im Durchschnitt 500000 Vergleiche und im schlimmsten Fall 1000000 Vergleiche; eine binäre Suche benötigt maximal 20 Vergleiche, selbst im schlimmsten Fall.
files := []string{"Test.conf", "util.go", "Makefile", "misc.go", "main.go"}
target := "Makefile"
sort.Strings(files)
i := sort.Search(len(files),
func(i int) bool { return files[i] >= target })
if i < len(files) && files[i] == target {
fmt.Printf("found \"%s\" at files[%d]\n", files[i], i)
}
Nur hatte eine ähnliche Frage und beschloss, einige der Vorschläge in diesem Thread auszuprobieren.
Ich habe die besten und schlechtesten Szenarien von 3 Arten von Suchvorgängen getestet:
Hier ist der Funktionscode:
func belongsToMap(lookup string) bool {
list := map[string]bool{
"900898296857": true,
"900898302052": true,
"900898296492": true,
"900898296850": true,
"900898296703": true,
"900898296633": true,
"900898296613": true,
"900898296615": true,
"900898296620": true,
"900898296636": true,
}
if _, ok := list[lookup]; ok {
return true
} else {
return false
}
}
func belongsToList(lookup string) bool {
list := []string{
"900898296857",
"900898302052",
"900898296492",
"900898296850",
"900898296703",
"900898296633",
"900898296613",
"900898296615",
"900898296620",
"900898296636",
}
for _, val := range list {
if val == lookup {
return true
}
}
return false
}
func belongsToSwitch(lookup string) bool {
switch lookup {
case
"900898296857",
"900898302052",
"900898296492",
"900898296850",
"900898296703",
"900898296633",
"900898296613",
"900898296615",
"900898296620",
"900898296636":
return true
}
return false
}
Best-case Szenarien wählen das erste Element in Listen aus, Worst-case-Szenarien verwenden einen nicht vorhandenen Wert.
Hier sind die Ergebnisse:
BenchmarkBelongsToMapWorstCase-4 2000000 787 ns/op
BenchmarkBelongsToSwitchWorstCase-4 2000000000 0.35 ns/op
BenchmarkBelongsToListWorstCase-4 100000000 14.7 ns/op
BenchmarkBelongsToMapBestCase-4 2000000 683 ns/op
BenchmarkBelongsToSwitchBestCase-4 100000000 10.6 ns/op
BenchmarkBelongsToListBestCase-4 100000000 10.4 ns/op
Die Switch-Anweisung gewinnt in allen Fällen, der Worst Case ist überraschenderweise schneller als der Best Case.
Maps sind am schlechtesten und Listen sind näher an der Switch-Anweisung.
Also lautet die Moral der Geschichte: Wenn Sie eine statische, relativ kleine Liste haben, ist die Switch-Anweisung der beste Weg.
Das obige Beispiel mit sort kommt der Sache nahe, aber im Falle von Strings verwenden Sie einfach SearchString:
files := []string{"Test.conf", "util.go", "Makefile", "misc.go", "main.go"}
target := "Makefile"
sort.Strings(files)
i := sort.SearchStrings(files, target)
if i < len(files) && files[i] == target {
fmt.Printf("found \"%s\" at files[%d]\n", files[i], i)
}
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.