wake-up-neo.net

Wie entferne ich das Element des struct array in einer Schleife in Golang?

Problem

Ich habe eine Reihe von Strukturen:

type Config struct {
  Applications []Application
}

Hinweis: Config - ist eine Struktur für json.Decode.

config = new(Config)
_ = decoder.Decode(&config)

In der Schleife habe ich einige Bedingung und Elementlöschung durch Schlüssel.

for i, application := range config.Applications {
  if i == 1 {
    config.Applications = _removeApplication(i, config.Applications)
  }
}

func _removeApplication(i int, list []Application) []Application {
  if i < len(list)-1 {
    list = append(list[:i], list[i+1:]...)
  } else {
    log.Print(list[i].Name)
    list = list[:i]
  }

  return list
}

Ich habe aber immer einen Fehler "Außer Reichweite". Was ist der beste Weg, ein Element nach Schlüssel aus einem Array von Strukturen zu löschen?

15
Alex Pliutau

Zitieren aus der Slice Tricks Seite, die das Element am Index i löscht:

a = append(a[:i], a[i+1:]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]

Wenn Sie planen, Elemente aus dem Slice zu löschen, über das Sie gerade eine Schleife erstellen, kann dies zu Problemen führen. Dies ist der Fall, wenn das Element, das Sie entfernen, das aktuelle ist (oder ein vorheriges Element, das bereits überlaufen ist), da nach dem Löschen alle nachfolgenden Elemente verschoben werden, die range-Schleife dies jedoch nicht weiß und den Index weiterhin inkrementiert und Sie eines überspringen Element.

Sie können dies vermeiden, indem Sie eine Abwärtsschleife verwenden:

for i := len(config.Applications) - 1; i >= 0; i-- {
    application := config.Applications[i]
    // Condition to decide if current element has to be deleted:
    if haveToDelete {
        config.Applications = append(config.Applications[:i],
                config.Applications[i+1:]...)
    }
}
35
icza

Diese Frage ist etwas älter, aber ich habe auf StackOverflow keine Antwort gefunden, die den folgenden Trick aus den Slice Tricks erwähnt, um eine Liste zu filtern: 

b := a[:0]
for _, x := range a {
    if f(x) {
        b = append(b, x)
    }
}

In diesem Fall könnte eine Funktion, die bestimmte Elemente löscht, folgendermaßen aussehen:

func removeApplications(apps []Applications) []Applications {
    filteredApps := apps[:0]
    for _, app := apps {
        if !removeApp {
            filteredApps = append(filteredApps, app)
        }
    }
    return filteredApps
}
3
treigerm

Sie erhalten diesen Fehler, weil Sie eine Schleife über ein Slice mit einem Anfangsbereich von X-Länge ausführen, der zu X-n wurde, weil Sie einige Elemente während der Schleife entfernen.

Wenn Sie ein Element an einem bestimmten Index aus einem Slice löschen möchten, können Sie dies folgendermaßen tun:

sliceA = append(sliceA[:indexOfElementToRemove], sliceA[indexOfElementToRemove+1:]...)
3
gdg

Ich denke der einfache Weg ist 

var (
  slice = []int{1,2,3,4,5}
  pos int
)
    for _, i := range slice {
        if i == 3 {
            slice = append(slice[:pos], slice[pos+1:]...)
            if pos > 0 {
                pos = pos - 1
            }
            continue
        }
        pos++
    }

hier ist ... https://play.golang.org/p/pK3B5Mii9k

1
Martin Prestone