The delete function
Sometimes an entry has to go. A shop stops selling an item, or a player leaves the game. Go has a built-in function for it: delete(m, key). It takes the map and then the key, and removes the key together with its value. Like len, it is built into the language, so it needs no import and no package name in front.
animals := map[string]int{"cat": 4, "dog": 2, "rabbit": 1}
delete(animals, "rabbit")
fmt.Println(len(animals)) // 2
The length drops by 1, because the key and its value are both gone. The call changes the map itself, so there is nothing to assign back, unlike append for a slice.
Deleting a key that isn't there
Deleting a missing key does nothing, and there is no error. After delete(animals, "rabbit") a second time, or delete(animals, "zebra"), the map still has 2 keys. Deleting from a nil map is also allowed. This is handy: you don't have to check the key before you delete it.
It is also safe to call delete inside a for ... range loop over the same map. The entries you delete will not appear later in the loop. For example, deleting every even value from {"a": 1, "b": 2, "c": 3, "d": 4} leaves map[a:1 c:3].
After the delete
Watch out: once the rabbit is deleted, animals["rabbit"] gives 0, the zero value of an int. That looks like a rabbit count of 0, even though the key is gone. Only the comma-ok lookup tells you the key is not there:
_, ok := animals["rabbit"]
fmt.Println(ok) // false
This matters when you think of setting the value to 0 as a way to delete. After m["pen"] = 0 the key is still in the map, with a count of 0, and len(m) is still 1. If you want the entry gone, use delete.
The task: the last rabbit
A pet shop keeps animals, where each key is a kind of animal and each value is how many the shop has. It starts as cat: 4, dog: 2 and rabbit: 1. The last rabbit has just gone home with a family.
- Below the first
fmt.Println, which prints 3, calldelete(animals, "rabbit"). - Print
len(animals)again. One key is gone, so it prints 2.
The code at the bottom checks whether any rabbits are left with a comma-ok lookup. The key is gone, so ok is false and the else branch runs.
animals := map[string]int{"cat": 4, "dog": 2, "rabbit": 1}
fmt.Println(len(animals))
delete(animals, "rabbit")
fmt.Println(len(animals))
if _, ok := animals["rabbit"]; ok {
fmt.Println("We still have rabbits")
} else {
fmt.Println("No rabbits left")
}
The output is:
3
2
No rabbits left
Common mistakes
- Writing
animals = delete(animals, "rabbit"). The function returns nothing, so that doesn't compile. - Passing only the key.
deleteneeds the map first, then the key. - Printing
lenbefore the delete and expecting the new number. The length changes only after the call.
Key takeaways
delete(m, key)removes the key and its value, and the length drops by 1.- It changes the map in place; nothing is assigned back.
- Deleting a missing key does nothing.
- After a delete, a plain lookup gives the zero value; use comma-ok to see that the key is gone.
