是否存在可以从GO中的地图中弹出(键,值)对的现有函数?我使用pop而不是remove,因为pop会在删除(key,value)的索引之后重新排列元素。
以下代码为例:
package main
import "fmt"
func main() {
mapp := make(map[int]int)
fmt.Println("before removal:")
for i := 1; i < 7; i++ {
mapp[i] = i
}
fmt.Println(mapp)
delete(mapp, 2)
fmt.Println("\nafter the removal:")
for i := 1; i < 7; i++ {
fmt.Println(i, mapp[i])
}
}
产生以下输出:
before removal:
map[1:1 2:2 3:3 4:4 5:5 6:6]
after the removal:
1 1
2 0
3 3
4 4
5 5
6 6
我们注意到索引位置2为空。我希望输出如下:
before removal:
map[1:1 2:2 3:3 4:4 5:5 6:6]
after the removal:
1 1
2 3
3 4
4 5
5 6
此功能是否已经在GO中,或者我是否必须实施它?
谢谢!
答案 0 :(得分:3)
我认为你误解了map
是什么以及它是如何运作的。你不应该把它看作是一个“有差距的数组”,而是作为一个经典的hash table。
要回答您的问题,当您使用delete()
时,该值会从map
中删除,问题在于您如何迭代地图的“值”。
为了帮助您理解:
mapp := make(map[int]int)
fmt.Println(2, mapp[2])
将打印
2 0
为什么?仅仅因为当请求的密钥不存在时,我们得到值类型的零值。在这种情况下,值类型为int,因此零值为0.
因此,您希望在打印之前查看地图中是否存在密钥,并且必须使用双值赋值,如下所示:
for i := 1; i < 7; i++ {
if value, exists := mapp[i]; exists {
fmt.Println(i, value)
}
}
它会打印
1 1
3 3
4 4
5 5
6 6
不是你想要的,但你可以直接用map
获得。
您可以查看this blog post以获取更多信息和示例。
如果您真的想要一个可以删除值的数组,请参阅Verran的答案并改为使用切片。
答案 1 :(得分:2)
When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next.
由此可见,无法自动将值向上移动一个位置以填充间隙,因为每次查看值时,键都可以位于不同的迭代位置,并且不能保证映射到2
的值将向上滑动到1
。
如果您想要执行此类操作,则必须手动将所有内容移至一个键值,例如:
for key := 2; key < len(map)-1; key++ {
map[key] = map[key+1]
}
或者,您可以使用切片,如果您知道需要“弹出”的索引,请创建一个省略该值的新切片:
value := slice[2]
slice = copy(slice[:2], slice[2+1:])