TheDeveloperBlog.com

Home | Contact Us

C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML

<< Back to GO

Golang map Examples

Perform fast lookups from keys to values with a map. Get map values and delete them.
Map. Travelers are rushing everywhere. In a subway system a map is essential. There is no logic to the network of tunnels. It is easy to get lost.
A Go map is a lookup table. It returns a value from a key—or tests if one exists. As with a subway map we locate values (destinations) from keys (tunnels).
First example. This map has string keys and string values. The key type is specified in the brackets after the "map" keyword. The value type comes afterward.Built-Ins

Part 1: We show the composite literal syntax in the "colors" table. We map the string "cat" to "black."

Part 2: We retrieve a value from the map at the key "snake." The string "green" is returned.

Golang program that uses map package main import "fmt" func main() { // Part 1: map animal names to color strings. // ... Create a map with composite literal syntax. colors := map[string]string{ "bird": "blue", "snake": "green", "cat": "black", } // Part 2: get color of snake. c := colors["snake"] fmt.Println(c) } Output green
Add with assignment. Suppose we want to add keys in a loop, or with separate statements. We cannot use an initialization expression here—we must assign to add keys.

Step 1: We create an empty map with the map keyword. The len() of the map at this point is 0.

Step 2: Here we add keys and associated values imperatively (with statements) in separate lines.

Step 3: We print the count of keys. The len operator (also used on arrays and slices) can be used on a map.

Len
Golang program that adds keys with assignments package main import "fmt" func main() { // Step 1: create an empty map. names := map[int]string{} // Step 2: add 3 pairs to the map in separate statements. names[990] = "file.txt" names[1009] = "data.xls" names[1209] = "image.jpg" // Step 3: there are 3 pairs in the map. fmt.Println(len(names)) } Output 3
Delete. We can add keys to a map by assigning them. But to delete a key and its value, we must use the delete built-in: the pair is entirely erased.

Here: We add three entries to a map. The length is 3. We then delete one key and the length is reduced to 2.

Argument 1: The first argument to delete() is the map from which we want to delete items.

Argument 2: The second argument is the value we want to delete. We specify "steve" here as that is the name we want to remove.

Golang program that uses delete built-in package main import "fmt" func main() { // Create an empty map and add 3 pairs to it. ids := map[string]int{} ids["steve"] = 10 ids["mark"] = 20 ids["adnan"] = 30 fmt.Println(len(ids)) // Delete one key from it. delete(ids, "steve") fmt.Println(len(ids)) } Output 3 2
Range, loop. With the "for" and "range" keywords we can iterate over a map. We must assign variables to the two return values returned by the range expression.

Note: We can use a blank identifier (the underscore "_") to store the result of a key or value if it will not be used.

Note 2: The value is optional in a range expression. Range can be used with slices, strings and maps.

range
Golang program that uses for-loop on map package main import "fmt" func main() { // Create a string to string map. animals := map[string]string{} animals["cat"] = "Mittens" animals["dog"] = "Spot" // Loop over the map. for key, value := range animals { fmt.Println(key, "=", value) } } Output cat = Mittens dog = Spot
Ok syntax. A key lookup in a map returns 2 values. If we do not need to access a variable elsewhere in the program, we can use the name "_" as its identifier to avoid errors.

Result 1: The first result from accessing a map is the value in the map if one exists.

Result 2: The second result (usually named "ok") is a boolean that indicates whether the key exists in the map.

Ok: In the if-statements, the ok variable is set and then tested. If true, the inner blocks are reached.

If

Tip: With the "comma ok" idiom, we can test for existence and store the lookup result in one statement.

Golang program that uses map, ok syntax package main import "fmt" func main() { counts := map[string]int{ "bird": 100, "frog": 200, "dog": 30, } // The ok variable is set to true. if count, ok := counts["bird"]; ok { fmt.Println("COUNT FOR BIRD:", count) } // The ok variable is set to false. // ... The string does not exist in the map. if _, ok := counts["cat"]; ok { fmt.Println("NOT REACHED") } } Output COUNT FOR BIRD: 100
Get keys from map. Here we get a slice of the keys from a map. We use a for-range loop over the map and then append all the keys to a slice. This slice contains the map's keys.

Tip: We can use the same code to get a slice of the values in a map. We change the for-loop to collect values not keys.

Convert Map, Slice
Golang program that gets slice of keys from map package main import "fmt" func main() { // Create map with three string keys. sizes := map[string]int{ "XL": 20, "L": 10, "M": 5, } // Loop over map and append keys to empty slice. keys := []string{} for key, _ := range sizes { keys = append(keys, key) } // This is a slice of the keys. fmt.Println(keys) } Output [XL L M]
Get values. Here we have a map of strings to strings. We loop over the "birds" map and collect the values from it. We place the values in a slice called "values."
Golang program that gets values package main import "fmt" func main() { // A simple map. birds := map[string]string{ "finch": "yellow", "parakeet": "blue", } // Place values in a string slice. values := []string{} for _, value := range birds { values = append(values, value) } // The values. fmt.Println(values) } Output [yellow blue]
Make, capacity. Make() can create a map with a capacity. This is the number of elements that can be placed in the map without resizing the map. A capacity optimizes the map.

Here: With a capacity of 200, we can add 200 keys with values to the map much faster. No reallocations are done in the map's internal code.

Golang program that uses make, map capacity package main import "fmt" func main() { // Create a map with a capacity of 200 pairs. // ... This makes adding the first 200 pairs faster. lookup := make(map[string]int, 200) // Use the new map. lookup["cat"] = 10 result := lookup["cat"] fmt.Println(result) } Output 10
Randomized range loop. The Go runtime randomizes the loop order over a map when the range keyword is used. This means programs that rely on a certain ordering of elements will fail sooner.

And: This improves program quality because programs will not develop dependencies on map orders.

Golang program that shows randomized range of map loop package main import "fmt" func main() { // Create a map with three key-value pairs. lookup := map[int]int{ 1: 10, 2: 20, 3: 30, } // Loop ten times. for i := 0; i < 10; i++ { // Print all keys in range loop over map. // ... Ordering is randomized. for key := range lookup { fmt.Print(key) fmt.Print(" ") } fmt.Println() } } Output 2 3 1 1 2 3 3 1 2 1 2 3 1 2 3 1 2 3 2 3 1 3 1 2 1 2 3 2 3 1
Func argument. In Go we place important units of logic in funcs. We can pass a map object to a func like any other type. We must specify the key and value type in the argument of the func.
Golang program that passes map as func argument package main import "fmt" func PrintGreen(colors map[string]int) { // Handle map argument. fmt.Println(colors["green"]) } func main() { // This map has two string keys. colors := map[string]int{ "blue": 10, "green": 20, } // Pass map to func. PrintGreen(colors) } Output 20
Func, early exit. Suppose we want to use a map to track items we have already handled. We test a map for items that are present, and exit early if we have already handled the item.

Note: This code is useful in many real-world programs. Suppose we want to avoid uploading a file twice—we can use a map to prevent this.

Golang program that uses func, early exit package main import "fmt" func Test(handled map[string]bool, name string) { // If name already exists, return early. if _, ok := handled[name]; ok { fmt.Println("ALREADY HANDLED: ", name) return } // Add to map so the next time this is called, we will return early. fmt.Println("ADDED: ", name) handled[name] = true } func main() { // Create example map of string keys, bool values. handled := map[string]bool{} // Call Test func with these strings. Test(handled, "bird") Test(handled, "cat") Test(handled, "bird") } Output ADDED: bird ADDED: cat ALREADY HANDLED: bird
Benchmark, map versus slice. A map accelerates lookups: it uses a special hash code to guide a search. Here we compare a map search to a slice search.

Version 1: In this code we look up a value from a small string map—only 4 keys are in the map. We locate the index of the value "bird."

Version 2: Here we loop over the 4 string elements in a string slice and try to find a matching element.

Result: For the small amount of data in this example, the slice performs better. A map is not always faster.

Golang program that benchmarks map, slice package main import ( "fmt" "time" ) func main() { lookup := map[string]int{ "cat": 0, "dog": 1, "fish": 2, "bird": 3} values := []string{"cat", "dog", "fish", "bird"} temp := 0 t0 := time.Now() // Version 1: search map with lookup. for i := 0; i < 10000000; i++ { v, ok := lookup["bird"] if ok { temp = v } } t1 := time.Now() // Version 2: search slice with for-loop. for i := 0; i < 10000000; i++ { for x := range(values) { if values[x] == "bird" { temp = x break } } } t2 := time.Now() // Benchmark results. fmt.Println(temp) fmt.Println(t1.Sub(t0)) fmt.Println(t2.Sub(t1)) } Output 3 119.0954ms map lookup 110.0776ms slice, for-loop
Benchmark, capacity. Here we test the speedup from using an accurate capacity. In this example both maps are created and populated with 1000 elements.

Version 1: This map is created with the make() function. It has an accurate capacity of 1000.

Version 2: This map has no capacity specified. It begins as an empty map. So the map must resize on its own.

Result: Using a capacity is over twice as fast. Specifying a capacity is a worthwhile optimization.

Golang program that benchmarks map with capacity package main import ( "fmt" "time" ) func main() { t0 := time.Now() // Version 1: use map with exact capacity. for i := 0; i < 10000; i++ { values := make(map[int]int, 1000) for x := 0; x < 1000; x++ { values[x] = x } if values[0] != 0 { fmt.Println(0) } } t1 := time.Now() // Version 2: no capacity. for i := 0; i < 10000; i++ { values := map[int]int{} for x := 0; x < 1000; x++ { values[x] = x } if values[0] != 0 { fmt.Println(0) } } t2 := time.Now() // Benchmark results. fmt.Println(t1.Sub(t0)) fmt.Println(t2.Sub(t1)) } Output 599.5427ms (600 ms) capacity = 1000 1.4154736s (1415 ms) no capacity used
Sort. A map stores its keys in an order that makes them fast to look up. We cannot sort a map. But we can extract the keys (or values) from a map and sort them.Sort: keys in map
String slices. One common kind of map has string slices as the values. In another example, we append strings to the values in a string slice map.Map, String Slices
Struct keys. A struct can be used as the key to a map. With structs, we can create compound keys. A key can contain an int and a string together.Struct: map keys
A summary. We used the map built-in to link keys to values. We tested that keys exist and we retrieved the appropriate values. A map provides a clear performance win.
© TheDeveloperBlog.com
The Dev Codes

Related Links:


Related Links

Adjectives Ado Ai Android Angular Antonyms Apache Articles Asp Autocad Automata Aws Azure Basic Binary Bitcoin Blockchain C Cassandra Change Coa Computer Control Cpp Create Creating C-Sharp Cyber Daa Data Dbms Deletion Devops Difference Discrete Es6 Ethical Examples Features Firebase Flutter Fs Git Go Hbase History Hive Hiveql How Html Idioms Insertion Installing Ios Java Joomla Js Kafka Kali Laravel Logical Machine Matlab Matrix Mongodb Mysql One Opencv Oracle Ordering Os Pandas Php Pig Pl Postgresql Powershell Prepositions Program Python React Ruby Scala Selecting Selenium Sentence Seo Sharepoint Software Spellings Spotting Spring Sql Sqlite Sqoop Svn Swift Synonyms Talend Testng Types Uml Unity Vbnet Verbal Webdriver What Wpf