问题描述
我是Golang的新手,我试图根据另一个切片中的元素删除一个切片中的元素。
例如
输入片段: urlList:= [] string {test,abc,def,ghi}
删除片段的元素: 期望输出片段: 这是我试过的。 但它没有按我的预期工作。我不知道我在想什么。 问题是,当您从原始列表中删除一个元素时,所有随后的元素被移动。但是 由于 一种可能的解决方案是在外循环中不要使用 remove:= [] string {abc,test} $ c $
urlList:= [] string {def,ghi}
func main(){
$ b $ urllist:= [] string {test,abc,def,ghi}
remove:= [] string {abc,test}
loop:
for i,url:= range urlList {
for _,rem:=范围删除{
if url == rem {
urlList = append(urlList [:i],urlList [i + 1:] ...)
continue loop
}
}
}
for _,v:= range urlList {
fmt.Println(v)
}
}
范围
循环并不知道你改变了底层slice,并且会照常增加索引,即使在这种情况下它不应该是因为你跳过一个元素。
remove
列表包含2个正确的元素在原始列表中相邻,第二个(本例中为abc
)将不会被检查并且不会被删除。
range
,并且在删除元素时,手动减少索引 i -
因为继续下一次迭代,它会自动递增:
urlList:= [] string {test,abc,def,ghi}
remove:= [] string {abc,test }
loop:
for i:= 0;我< LEN(urlList); i ++ {
url:= urlList [i]
for _,rem:=范围删除{
如果url == rem {
urlList = append(urlList [:i], urlList [i + 1:] ...)
i-- //重要提示:减少索引
继续循环
}
}
}
fmt.Println(urlList)
输出:
[def ghi]
$ b $注意:由于外层循环在内层循环之后不包含任何内容,因此可以将标签+继续替换为一个简单的 code> break :
urlList:= [] string {test, abc,def,ghi}
remove:= [] string {abc,test}
for i:= 0;我< LEN(urlList); i ++ {
url:= urlList [i]
for _,rem:=范围删除{
如果url == rem {
urlList = append(urlList [:i], urlList [i + 1:] ...)
i-- //重要提示:减少索引
break
}
}
}
fmt.Println(urlList)
试试。
替代
另一种方法是外部循环向下,因此不需要手动减少(或增加)索引变量,因为移位的元素不受影响(已经处理向下方向)。
I am complete newbie in Golang, I am trying to remove elements in one slice based on the elements in another slice.e.g.
input slice : urlList := []string{"test", "abc", "def", "ghi"}
elements to remove slice : remove := []string{"abc", "test"}
expected output slice : urlList := []string{"def", "ghi"}
This is what I tried.
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)
}
}
But it's not working as I expected. I don't know what I am missing.
The problem is that when you remove an element from the original list, all subsequent elements are shifted. But the range
loop doesn't know that you changed the underlying slice and will increment the index as usual, even though in this case it shouldn't because then you skip an element.
And since the remove
list contains 2 elements which are right next to each other in the original list, the second one ("abc"
in this case) will not be checked and will not be removed.
One possible solution is not to use range
in the outer loop, and when you remove an element, you manually decrease the index i--
because continuing with the next iteration it will get auto-incremented:
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)
Output:
[def ghi]
Note:
Since the outer loop contains nothing after the inner loop, you can replace the label+continue with a simple 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)
Try it on Go Playground.
Alternative
An alternative to this would be for the outer loop to go downward, so no need to manually decrease (or increase) the index variable because the shifted elements are not affected (already processed due to the downward direction).
这篇关于删除切片中的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!