2015-03-12 15 views
13

ProblemWie in golang

Ich habe Array von Strukturen Element struct Array in Schleife entfernen:

type Config struct { 
    Applications []Application 
} 

Hinweis: Config - ist ein struct für json.Decode.

In Schleife habe ich einige Bedingung und Element Löschung per 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 
} 

Aber ich habe immer "out of range" Fehler. Was ist der beste Weg, Element für Schlüssel aus einem Array von Strukturen zu löschen?

Antwort

33

von der Slice Tricks Seite Zitiert das Element an Index Löschen i:

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

Beachten Sie, wenn Sie planen, Elemente aus der Scheibe zu löschen, die Sie gerade Schleifen über, die Probleme verursachen können. Und wenn das Element, das Sie entfernen, das aktuelle Element ist (oder ein vorheriges Element bereits durchlaufen wurde), werden nach dem Löschen alle nachfolgenden Elemente verschoben, aber die range-Schleife weiß nichts darüber und erhöht den Index immer noch und Sie überspringen eins Element.

Sie können dies vermeiden, indem eine nach unten gerichtete Schleife:

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:]...) 
    } 
} 
+0

Was das ist ... in dem Zufügen-Befehl für? – Michael

+0

@Michael Das '...' sagt, dass Sie eine Scheibe haben, die Sie übergeben möchten, um den Wert des _varijadic_ Parameters zu sein. ['append()'] (https://golang.org/pkg/builtin/#append) hat einen variadischen Parameter, der normalerweise durch _enumerating_ die Elemente aufgerufen wird, aber in diesem Fall nennen wir ihn _having_ die Elemente in einem Slice und _passing_ dieses Slice, und wir wollen, dass die Elemente des Slices die Werte des Variadic-Parameters sind (und wir wollen nicht, dass das Slice selbst ein einzelnes Element für den Variadic-Parameter ist). – icza

3

Sie erhalten diese Fehler, weil Sie eine Schleife über eine Scheibe mit einem inital Bereich von X Länge tun, die Xn wurde, weil Sie einige Elemente entfernen während der Schleife.

Wenn Sie einen Artikel zu einem bestimmten Index aus einer Scheibe löschen möchten, können Sie es auf diese Weise tun:

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

Diese Frage ist etwas älter, aber ich habe nicht eine andere Antwort auf Stackoverflow gefunden, die führt die folgenden Trick aus der Slice Tricks eine Liste zu filtern:

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

Also in diesem Fall eine Funktion, die bestimmte Elemente löscht könnte wie folgt aussehen:

1

Ich denke, die einfache Art und Weise

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