問題
構造体の配列があります:
type Config struct {
Applications []Application
}
注:Config-json.Decodeの構造体です。
config = new(Config)
_ = decoder.Decode(&config)
ループでは、いくつかの条件とキーによる要素の削除があります。
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
}
しかし、常に「範囲外」エラーが発生します。構造体の配列からキーで要素を削除する最良の方法は何ですか?
インデックスi
の要素を削除する Slice Tricks ページからの引用:
a = append(a[:i], a[i+1:]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]
現在ループしているスライスから要素を削除する場合は、問題が発生する可能性があることに注意してください。また、削除した要素が現在の要素(または既にループされた前の要素)である場合は、削除後に後続のすべての要素がシフトされますが、range
ループはこれを認識せず、引き続きインクリメントしますインデックスと1つの要素をスキップします。
これを回避するには、下向きのループを使用します。
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:]...)
}
}
このエラーが発生するのは、ループ中に一部の要素を削除したためにX-nになった初期長X範囲のスライスでループを実行しているためです。
スライスから特定のインデックスにあるアイテムを削除する場合は、次の方法で行うことができます。
sliceA = append(sliceA[:indexOfElementToRemove], sliceA[indexOfElementToRemove+1:]...)
この質問は少し古いですが、リストをフィルタリングするための Slice Tricks からの次のトリックについて言及しているStackOverflowで別の回答を見つけていません。
b := a[:0]
for _, x := range a {
if f(x) {
b = append(b, x)
}
}
したがって、この場合、特定の要素を削除する関数は次のようになります。
func removeApplications(apps []Applications) []Applications {
filteredApps := apps[:0]
for _, app := apps {
if !removeApp {
filteredApps = append(filteredApps, app)
}
}
return filteredApps
}
簡単な方法だと思います
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++
}