it-swarm.com.de

Hat Go ein "if x in" -Konstrukt ähnlich wie Python?

Ohne Durchlaufen Sie das gesamte Array. Wie kann ich mit Go prüfen, ob x im Array vorhanden ist? Hat die Sprache ein Konstrukt?

Wie Python: if "x" in array: ...

239
user1529891

Es gibt keinen eingebauten Operator, um dies in Go zu tun. Sie müssen das Array durchlaufen. Sie können Ihre eigene Funktion schreiben, um dies zu tun:

func stringInSlice(a string, list []string) bool {
    for _, b := range list {
        if b == a {
            return true
        }
    }
    return false
}

Wenn Sie in der Lage sein möchten, die Mitgliedschaft zu überprüfen, ohne die gesamte Liste zu durchlaufen, müssen Sie eine Karte anstelle eines Arrays oder Slices wie folgt verwenden:

visitedURL := map[string]bool {
    "http://www.google.com": true,
    "https://Paypal.com": true,
}
if visitedURL[thisSite] {
    fmt.Println("Already been here.")
}
291
andybalholm

Eine andere Lösung, wenn die Liste statische Werte enthält.

beispiel: Überprüfung auf einen gültigen Wert aus einer Liste gültiger Werte:

func IsValidCategory(category string) bool {
    switch category {
    case
        "auto",
        "news",
        "sport",
        "music":
        return true
    }
    return false
}
79
sebest

Dies ist ein Zitat aus dem Buch "Programming in Go: Erstellen von Anwendungen für das 21. Jahrhundert":

Die Verwendung einer einfachen linearen Suche ist die einzige Option für unsortierte Daten und für kleine Segmente (bis zu Hunderten von Elementen) geeignet. Bei größeren Segmenten ist die lineare Suche jedoch sehr ineffizient, insbesondere wenn Suchvorgänge wiederholt ausgeführt werden. Im Durchschnitt muss jedes Mal die Hälfte der Elemente verglichen werden.

Go bietet eine sort.Search () -Methode, die den binären Suchalgorithmus verwendet: Dies erfordert den Vergleich von jeweils nur log2 (n) Elementen (wobei n die Anzahl der Elemente ist). Um dies zu relativieren, erfordert eine lineare Suche nach 1000000 Artikeln im Durchschnitt 500000 Vergleiche, im schlimmsten Fall 1000000 Vergleiche. Eine binäre Suche benötigt auch im schlimmsten Fall höchstens 20 Vergleiche.

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

https://play.golang.org/p/UIndYQ8FeW

47
AlexTT

Das obige Beispiel für die Verwendung von sort ist in der Nähe, aber im Fall von Zeichenfolgen 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)
}

https://golang.org/pkg/sort/#SearchStrings

22
Robert Weber

Hatte gerade eine ähnliche Frage und habe beschlossen, einige der Vorschläge in diesem Thread auszuprobieren.

Ich habe die besten und schlechtesten Szenarien für drei Arten der Suche verglichen:

  • mit einer Karte
  • mit einer Liste
  • mit einer switch-Anweisung

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
}

in Best-Case-Szenarien wird das erste Element in Listen ausgewählt, in Worst-Case-Szenarien wird kein vorhandener Wert verwendet.

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

Switch gewinnt auf ganzer Linie, der Worst-Case ist schneller als der Best-Case. Karten sind die schlechtesten und die Liste ist näher zu wechseln.

Die Moral lautet also: Wenn Sie eine statische, relativ kleine Liste haben, ist die switch-Anweisung der richtige Weg.

17
Igor

Eine andere Option ist die Verwendung einer Karte als Set. Sie verwenden nur die Schlüssel, und der Wert ist so etwas wie ein Boolescher Wert, der immer wahr ist. Dann können Sie leicht überprüfen, ob die Karte den Schlüssel enthält oder nicht. Dies ist nützlich, wenn Sie das Verhalten einer Menge benötigen. Wenn Sie einen Wert mehrmals hinzufügen, ist er nur einmal in der Menge enthalten.

Hier ist ein einfaches Beispiel, in dem ich einer Karte Zufallszahlen als Schlüssel hinzufüge. Wenn dieselbe Nummer mehrmals generiert wird, ist es egal, dass sie nur einmal in der endgültigen Karte angezeigt wird. Dann benutze ich eine einfache if-Prüfung, um festzustellen, ob sich ein Schlüssel in der Karte befindet oder nicht.

package main

import (
    "fmt"
    "math/Rand"
)

func main() {
    var MAX int = 10

    m := make(map[int]bool)

    for i := 0; i <= MAX; i++ {
        m[Rand.Intn(MAX)] = true
    }

    for i := 0; i <= MAX; i++ {
        if _, ok := m[i]; ok {
            fmt.Printf("%v is in map\n", i)
        } else {
            fmt.Printf("%v is not in map\n", i)
        }
    }
}

Hier ist es auf dem Spielplatz

7
nobled