Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a map contains a key in Go?

I know I can iterate over a map m by,

for k, v := range m { ... } 

and look for a key but is there a more efficient way of testing a key's existence in a map?

I couldn't find the answer in the language spec.

like image 642
grokus Avatar asked Jan 12 '10 16:01

grokus


People also ask

How do you check if a key exists in map in Golang?

When we execute the call to mymap['key'] we get back two distinct values, the first of which is the value of the key and the second is a bool value which represents whether or not the given key exists within the map. This second value is what we use to check if a given key exists in the if statement on line 13.

How do I get the map key in Go?

You can retrieve the value assigned to a key in a map using the syntax m[key] . If the key exists in the map, you'll get the assigned value. Otherwise, you'll get the zero value of the map's value type.

Are maps pointers in Go?

Maps, like channels, but unlike slices, are just pointers to runtime types. As you saw above, a map is just a pointer to a runtime. hmap structure. Maps have the same pointer semantics as any other pointer value in a Go program.


2 Answers

One line answer:

if val, ok := dict["foo"]; ok {     //do something here } 

Explanation:

if statements in Go can include both a condition and an initialization statement. The example above uses both:

  • initializes two variables - val will receive either the value of "foo" from the map or a "zero value" (in this case the empty string) and ok will receive a bool that will be set to true if "foo" was actually present in the map

  • evaluates ok, which will be true if "foo" was in the map

If "foo" is indeed present in the map, the body of the if statement will be executed and val will be local to that scope.

like image 107
marketer Avatar answered Oct 14 '22 02:10

marketer


In addition to The Go Programming Language Specification, you should read Effective Go. In the section on maps, they say, amongst other things:

An attempt to fetch a map value with a key that is not present in the map will return the zero value for the type of the entries in the map. For instance, if the map contains integers, looking up a non-existent key will return 0. A set can be implemented as a map with value type bool. Set the map entry to true to put the value in the set, and then test it by simple indexing.

attended := map[string]bool{     "Ann": true,     "Joe": true,     ... }  if attended[person] { // will be false if person is not in the map     fmt.Println(person, "was at the meeting") } 

Sometimes you need to distinguish a missing entry from a zero value. Is there an entry for "UTC" or is that 0 because it's not in the map at all? You can discriminate with a form of multiple assignment.

var seconds int var ok bool seconds, ok = timeZone[tz] 

For obvious reasons this is called the “comma ok” idiom. In this example, if tz is present, seconds will be set appropriately and ok will be true; if not, seconds will be set to zero and ok will be false. Here's a function that puts it together with a nice error report:

func offset(tz string) int {     if seconds, ok := timeZone[tz]; ok {         return seconds     }     log.Println("unknown time zone:", tz)     return 0 } 

To test for presence in the map without worrying about the actual value, you can use the blank identifier (_) in place of the usual variable for the value.

_, present := timeZone[tz] 
like image 35
peterSO Avatar answered Oct 14 '22 03:10

peterSO