我在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)
    }
}但不像我预料的那样起作用了。我不知道我错过了什么。
发布于 2015-02-24 15:21:15
问题是,当从原始列表中删除元素时,所有后续元素都会被移动。但是range循环不知道您更改了基础片并将像往常一样增加索引,尽管在本例中不应该这样做,因为这样就可以跳过元素。
而且,由于remove列表包含两个元素,它们在原始列表中彼此相邻的是,因此第二个元素(在本例中为"abc")将不会被选中,也不会被删除。
一个可能的解决方案是在外部循环中不使用range,当您删除一个元素时,手动减少索引range,因为继续下一次迭代它将自动递增:
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]注:
由于外部循环在内环之后不包含任何内容,所以可以用简单的label+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)在围棋游乐场上试一试。
替代
另一种替代方法是外部循环向下,因此不需要手动减少(或增加)索引变量,因为移位的元素不受影响(由于向下方向已经处理了)。
https://stackoverflow.com/questions/28699485
复制相似问题