由于切片中的项目数正在更改,因此如何安全地从切片中删除项目

时间:2018-11-08 03:09:06

标签: go

一旦我遍历了用户切片,则需要根据某些条件从切片中删除一些用户。我将多次遍历此用户片,并慢慢删除一些元素。

从其他语言中我知道在循环时从集合中删除项目并不安全。因此,我要做的是将要删除的元素存储在映射toMutate中。原始循环完成后,请继续尝试从切片中删除元素。

toMutate := make(map[int]User, 100)
for idx, u := range c.users {
  if someCondition {
    toMutate[idx] = u
  }
}

然后我调用此函数从用户的切片中删除项目。

for idx, u := range toMutate {
  c.users = append(c.users[:idx], c.users[idx+1:]...)
}

现在我得到一个错误:

  

紧急:运行时错误:切片范围超出范围

我想我知道为什么我得到了错误。每次迭代,我都会从切片中删除一个元素。 因此,由于项数已更改,因此我的idx值已关闭。

您如何处理这种情况?

2 个答案:

答案 0 :(得分:4)

对于每个要删除的值,我认为这比将其保存在地图中并重新切片更有效。

v1

但是更好的方法是使用其他数据结构,例如链表或为删除而优化的数据。

数组(切片)对于删除中间的元素效率不高。

答案 1 :(得分:1)

属意如下:

toMutate := []int {}
for idx := range c.users {
    if someCondition {
        toMutate = append(toMutate, idx)
    }
}
//...
sort.Sort(sort.Reverse(sort.IntSlice(toMutate)))
//...
for _, u := range toMutate {
   c.users = append(c.users[:u], c.users[u+1:]...)
}