= Go Maps = '''Maps''' are a mapping data type. There is also a built-in `maps` module for working with the data type. <> ---- == Type == === Example === {{{ // To declare and initialize m := make(map[string]int) m["a"] = 1 m["b"] = 2 // Alternatively... m2 := map[string]int{"a": 1, "b": 2} fmt.Println(m["a"]) //key exists, prints 1 fmt.Println(m["c"]) //key does not exist, prints the zero value c, ok = m["c"] if !ok { //ok indicates if the key exists fmt.Println(c) } delete(m, "a") for key, value := range m { fmt.Printf("%s = %s\n", key, value) } }}} === Range over a Map === The simplest and built-in way to range over a map is: {{{ for key, value := range m { fmt.Printf("%s = %s\n", key, value) } }}} In certain circumstances, it may be more efficient to import the `maps` module; see below. === Counter === A map can be used as a counter very easily. Because nonexistent keys return the zero value, it isn't necessary to check for existence. {{{ counter := make(map[string]int) for i = 0; i < len(mylist); i++ { counter[mylist[i]]++ } }}} === Set === A map can be used as a set. The key is to use a value type that does not occupy any space in memory. {{{ set := make(map[string]struct{}) set["a"] = struct{} set["b"] = struct{} delete(set, "a") // Intersection intersect := make(map[string]struct{}) for k, _ := range set { if anotherset[k] { intersect[k] = struct{} } } // Union union := make(map[string]struct{}) for k, _ := range set { union[k] = struct{} } for k, _ := range anotherset { union[k] = struct{} } // In-place union for k, _ := range anotherset { set[k] = struct{} } }}} === Notes === A map has to be either declared with `make` or initialized with a map literal, because the zero value of a map is `nil`. Any comparable type can be used as the key in a map. This includes: * basic types like strings and integers * pointers * structs * channels * interfaces The most notable types ''not'' allowed are slices and maps themselves. ---- == Module == The following iteration functions are available. These can be more efficient or appropriate that the built-in method of ranging over a map. ||'''Function''' ||'''Return Value'''||'''Example''' || ||`maps.All(m)` ||iterator ||`for key, value := maps.All(m) ...` || ||`maps.Keys(m)` ||iterator ||`for key := maps.Keys(m) ...` || ||`maps.Values(m)` ||iterator ||`for value := maps.Values(m) ...` || Note that an iterator is perfect for ranging over, or for passing to another function that is prepared to handle any generic sequence (e.g. `slices.Collect`), but is not the same as a slice. There are also the following constructor functions: * `maps.Clone(m)` for creating a new map from another map * `maps.Collect(s)` for creating a new map from an iterator of pairs (such as what is created by `maps.All(m)`) There are also some modification functions. * `maps.Copy(dest, src)` sets keys and values into a destination map according to a source map * `maps.DeleteFunc(m, func)` deltes keys programmatically * `maps.Insert(m, s)` sets keys and values into a map according to an iterator of pairs There are two functions for checking equality. `maps.Equal(m1, m2)` uses built-in equality while `maps.EqualFunc(m1, m2, func)` uses a user-provided function to check equality of values. Keys are checked using built-in equality still. ---- CategoryRicottone