Go basic series (7): Map type

Source: Internet
Author: User
Tags key string

Map in go is used to store key/value pairs. It is often called hash, dictionary, and associated array in other places. These are different names for the same data structure, they are all used to map keys to values after hash function processing to implement a one-to-one correspondence relationship.

Internal Structure of Map

A simple map structure:

When storing elements in a map, each key is processed by a hash operation, and an appropriate hash bucket (hash bucket) is selected based on the calculated hash value ), store each key/value in the selected hash bucket. If the entire map is subdivided into multiple categories based on the bucket, each key may be stored in different buckets.

Therefore, the elements in the map are unordered and the chronological order is random. Even if the elements are stored in the same order twice, the chronological order cannot be guaranteed.

Because hash bucket is selected for key hash calculation, the key of map must be unique. Otherwise, if the calculated hash value is the same, a hash collision occurs.

When accessing and deleting elements, it is also similar. You must calculate the hash value of the key, find the corresponding hash bucket, and then find the key and value in the hash bucket.

In go, map is a pointer. The bottom layer of map is an array and two arrays are used. A lower layer array is used to package and save the key and value.

Create and Access Map

You can use make () to create a map. It first creates the underlying data structure, then creates a map, and points the map to the underlying data structure.

my_map := make(map[string]int)

Where[string]Indicates the Data Type of the map key,intIndicates the value corresponding to the key.

You can also create and initialize the value assignment directly using braces:

// Empty mapmy_map: = map [String] string {} // initialization value: my_map: = map [String] string {"red": "# da1337", "orange ": '# e95a22 "} // formatted value assignment my_map: = map [String] int {" Java ": 11," Perl ": 8," Python ": 13, // note that there must be no fewer commas at the end}

The map key can be any built-in data type (such as INT), or other data types that can be used for equivalent comparison through "=. Slice, pointer, and custom data types containing slice cannot be used as keys.

However, value can be of any type, for example, nesting a slice into map:

my_map := map[string][]int{}

When accessing the element in map, specify its key. Note that the string type key must be enclosed by quotation marks:

My_map: = map [String] int {"Java": 11, "Perl": 8, "Python": 13,} // access println (my_map ["Perl"]) // assign an existing key & valuemy_map ["Perl"] = 12 println (my_map ["Perl"]) // assign a new key & valuemy_map ["shell"] = 14 println (my_map ["shell"])
Nil map and empty Map

Empty map is a map without any Value assignment:

// Empty mapmy_map: = map [String] string {}

Nil map, which will not perform any initialization and will not point to any data structure:

// nil mapvar my_map map[string]string

The relationship between nil map and empty map is like that between nil slice and empty slice. Both are empty objects and no data is stored, but the former does not point to the underlying data structure, the latter points to the underlying data structure, except that the underlying object is a null object. Use the println output to view the following information:

package mainfunc main() {    var nil_map map[string]string    println(nil_map)    emp_map := map[string]string{}    println(emp_map)}

Output result:


So,The map type is actually a pointer..

Returned values of elements in Map

When accessing an element in map, there are two formats of returned values:

value := my_map["key"]value,exists := my_map["key"]

The first is to retrieve the value corresponding to the key in the map. If the key does not exist, the value returns 0 of the data type. For example, if int is 0, Boolean is false, and string is empty "".

The second method not only returns the value corresponding to the key, but also returns a Boolean value assigned to the exists variable based on whether the key exists. Therefore, if the key exists, the value is the corresponding value, and exists is true. If the key does not exist, the value is 0 (also 0 represented by each data type), and exists is false.

Let's take a look at the example:

my_map := map[string]int{                "Java":11,                "Perl":8,                "Python":13,            }value1 := my_map["Python"]value2,exists2 := my_map["Perl"]value3,exists3 := my_map["Shell"]println(value1)println(value2,exists2)println(value3,exists3)

The following result is output:

138 true0 false

In go, setting multiple return values is similar to this. Even if you write a function, you often set its exists attribute.

Len () and delete ()

The LEN () function is used to obtain the number of elements in the map, that is, there are multiple fewer keys. Delete () is used to delete a key in the map.

func main() {    my_map := map[string]int{        "Java":   11,        "Perl":   8,        "Python": 13,        "Shell":  23,    }    println(len(my_map))    // 4    delete(my_map,"Perl")    println(len(my_map))    // 3}
Test whether the element in map exists

Two methods can be used to test whether a key exists in map:

  1. It is determined based on the second return value of the map element.
  2. It is determined based on whether the returned value is 0 (0 varies with different data types ).

Method 1: directly access the element in map and assign it to two variables. The second variable is the modifier variable for the element.

my_map := map[string]int{                "Java":11,                "Perl":8,                "Python":13,            }value,exists := my_map["Perl"]if exists {    println("The key exists in map")}

You can combine the above two steps to look at the higher:

if value,exists := my_map["Perl"];exists {    println("key exists in map")}

Method 2: Determine based on the value returned by the map element. Because the value part of the map is of the int type, its 0 is the value 0.

my_map := map[string]int{                "Java":11,                "Perl":8,                "Python":13,            }value := my_map["Shell"]if value == 0 {    println{"not exists in map"}}

If the data type of MAP value is string, it determines whether it is null:

if value == "" {    println("not exists in map")}

Because the value in map may exist, but its value is 0, a false judgment will occur. For example, the following "shell" already exists, but its corresponding value is 0.

my_map := map[string]int{                "Java":11,                "Perl":8,                "Python":13,                "Shell":0,            }

Therefore, the first method should be used to determine whether an element exists.

Iterative traversal Map

Because map is a data structure of the key/value type and the key is the index of the map, key and value are returned when the range keyword is used to operate the map.

my_map := map[string]int{                "Java":11,                "Perl":8,                "Python":13,                "Shell":23,            }for key,value := range my_map {    println("key:",key," value:",value)}
Obtain all keys in the map

Go does not provide a function to directly obtain all the keys of the map. Therefore, you can only write it by yourself. The method is simple. Range traverses the map and puts the retrieved key into a server Load balancer to save it.

Package mainimport "FMT" func main () {my_map: = map [String] int {"Java": 11, "Perl": 8, "Python": 13, "shell": 23,} // Save the slice type of the key in the map. // The Slice type must be consistent with the map key type. Keys: = make ([] string, 0, len (my_map) // traverses the key in the map to keys for map_key, _: = range my_map {keys = append (keys, map_key)} FMT. println (KEYS )}

Note that the length of the Server Load balancer declared above must be 0; otherwise, it is declared as a server Load balancer with a length of 4 and a capacity of 4. All the four elements are null, And the append () the server Load balancer is directly resized once. As a result, the length of the Server Load balancer after append () is twice the length of the map. The first half is empty, and the second half is usually the key in the map.

Pass map to function

Map is a pointer, so the map is passed to the function, just copying this pointer, so the function's internal operations on map will directly modify the external map.

For example, addone () is used to add 1 to the value corresponding to the map key.

package mainfunc main() {    my_map := map[string]int{        "Java":   11,        "Perl":   8,        "Python": 13,        "Shell":  23,    }    println(my_map["Perl"])   // 8    addone(my_map,"Perl")     println(my_map["Perl"])   // 9}func addone(m map[string]int,key string) {    m[key] += 1}

Go basic series (7): Map type

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.