我是Golang的新手,我试图根据另一个切片中的元素删除一个切片中的元素.例如
输入切片: urlList := []string{"test", "abc", "def", "ghi"}
要删除切片的元素: remove := []string{"abc", "test"}
预期输出切片: urlList := []string{"def", "ghi"}
这是我试过的.
func main() {
urlList := []string{"test", "abc", "def", "ghi"}
remove := []string{"abc", "test"}
loop:
for i, url := range urlList {
for _, rem := range remove {
if url == rem {
urlList = append(urlList[:i], urlList[i+1:]...)
continue loop
}
}
}
for _, v := range urlList {
fmt.Println(v)
}
}
Run Code Online (Sandbox Code Playgroud)
但它并没有像我预期的那样发挥作用.我不知道我错过了什么.
问题是当您从原始列表中删除元素时,所有后续元素都会移位.但是range循环并不知道你改变了底层切片并且会像往常一样递增索引,即使在这种情况下它不应该因为你跳过一个元素.
并且由于remove列表包含原始列表中彼此相邻的 2个元素,因此"abc"将不会检查第二个(在这种情况下)并且不会将其删除.
一种可能的解决方案是不在range外部循环中使用,并且当您删除元素时,手动减少索引,i--因为继续下一次迭代它将自动递增:
urlList := []string{"test", "abc", "def", "ghi"}
remove := []string{"abc", "test"}
loop:
for i := 0; i < len(urlList); i++ {
url := urlList[i]
for _, rem := range remove {
if url == rem {
urlList = append(urlList[:i], urlList[i+1:]...)
i-- // Important: decrease index
continue loop
}
}
}
fmt.Println(urlList)
Run Code Online (Sandbox Code Playgroud)
输出:
[def ghi]
Run Code Online (Sandbox Code Playgroud)
注意:
由于外部循环在内部循环之后不包含任何内容,因此您可以使用简单的替换标签+ continue break:
urlList := []string{"test", "abc", "def", "ghi"}
remove := []string{"abc", "test"}
for i := 0; i < len(urlList); i++ {
url := urlList[i]
for _, rem := range remove {
if url == rem {
urlList = append(urlList[:i], urlList[i+1:]...)
i-- // Important: decrease index
break
}
}
}
fmt.Println(urlList)
Run Code Online (Sandbox Code Playgroud)
在Go Playground尝试一下.
替代
另一种方法是外循环向下,因此不需要手动减少(或增加)索引变量,因为移位的元素不受影响(由于向下方向已经处理).
| 归档时间: |
|
| 查看次数: |
7544 次 |
| 最近记录: |