迭代地从切片中删除元素
迭代切片时,由于移位而在循环中删除元素可能会很棘手后续元素。一种常见的错误方法是使用追加来删除元素,如下例所示:
<code class="go">a := []string{"abc", "bbc", "aaa", "aoi", "ccc"} for i := range a { // BAD if conditionMeets(a[i]) { a = append(a[:i], a[i+1:]...) } }</code>
此方法无法正常工作,因为循环不考虑移位的元素。要在迭代时正确删除元素,您可以使用向下循环或采用避免不断复制操作的替代方法。
向下循环
向下循环迭代相反的顺序,从最后一个元素开始。这种方法允许您删除元素,而无需手动递减循环变量:
<code class="go">a := []string{"abc", "bbc", "aaa", "aoi", "ccc"} for i := len(a) - 1; i >= 0; i-- { if conditionMeets(a[i]) { a = append(a[:i], a[i+1:]...) } }</code>
多次删除的替代方法
如果您需要删除大量对于元素,使用追加可能会由于过度复制而效率低下。另一种方法是创建一个新切片并仅复制不可删除的元素:
<code class="go">a := []string{"abc", "bbc", "aaa", "aoi", "ccc"} b := make([]string, len(a)) copied := 0 for _, s := range(a) { if !conditionMeets(s) { b[copied] = s copied++ } } b = b[:copied]</code>
多次删除的就地删除(通用)
就地删除技术涉及维护两个索引并在同一切片中分配不可删除的元素,同时将删除的元素位置归零:
<code class="go">a := []string{"abc", "bbc", "aaa", "aoi", "ccc"} copied := 0 for i := 0; i < len(a); i++ { if !conditionMeets(a[i]) { a[copied] = a[i] copied++ } } for i := copied; i < len(a); i++ { a[i] = "" // Zero places of removed elements for garbage collection } a = a[:copied]</code>
以上是如何在 Go 中迭代地从切片中删除元素?的详细内容。更多信息请关注PHP中文网其他相关文章!