go – 删除切片中的元素

我是Golang的新手,我试图根据另一个切片中的元素删除一个切片中的元素.
例如

input slice: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)
    }
}

但它并没有像我预期的那样发挥作用.我不知道我错过了什么.

问题是,当您从原始列表中删除元素时,将移动所有后续元素.但是范围循环不知道你改变了底层切片并且会像往常一样递增索引,即使在这种情况下它不应该因为你跳过一个元素.

并且由于删除列表包含原始列表中彼此相邻的2个元素,因此将不会检查第二个元素(在这种情况下为“abc”),并且不会将其删除.

一种可能的解决方案是不在外部循环中使用范围,并且当您删除元素时,手动减少索引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)

输出:

[def ghi]

注意:

由于外部循环在内部循环之后不包含任何内容,因此可以使用简单的中断替换标签“继续”:

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)

试试Go Playground.

替代

另一种方法是外循环向下,因此不需要手动减少(或增加)索引变量,因为移位的元素不受影响(由于向下方向已经处理).

https://stackoverflow.com/questions/28699485/remove-elements-in-slice

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:go – 删除切片中的元素