这篇文章涵盖了Golang地图类型的教程和实例
在我的上一篇文章中,介绍了Golang中的地图指南。
让我们看看Go语言中地图类型的例子。
如何在Golang中通过键或值对Map进行排序?
map 是一个有序的数据结构,在Golang中具有key-value 对。
我们必须写一个自定义代码来对地图进行排序。
例如,我们有一个字符串key和int values的地图。
打印地图时,返回的地图数据是随机的,而且顺序不被保证。
下面是打印地图的例子
package main
import (
"fmt"
)
func main() {
employees := map[string]int{"Kiran": 2030, "John": 10210,
"Mark": 25000}
fmt.Println(employees)
fmt.Println(employees)
fmt.Println(employees)
fmt.Println(employees)
fmt.Println(employees)
}
输出是
map[John:10210 Mark:25000 Kiran:2030]
map[John:10210 Mark:25000 Kiran:2030]
map[Kiran:2030 John:10210 Mark:25000]
map[Mark:25000 Kiran:2030 John:10210]
map[Kiran:2030 John:10210 Mark:25000]
现在,你如何根据键值对地图进行排序?
package main
import (
"fmt"
"sort"
)
func main() {
employees := map[string]int{"Kiran": 2030, "John": 10210, "Mark": 25000}
fmt.Println(employees)
keys := make([]string, 0, len(employees))
for k := range employees {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
fmt.Println(k, employees[k])
}
}
显示的地图是按键值排序的,输出是
map[Mark:25000 Kiran:2030 John:10210]
John 10210
Kiran 2030
Mark
如何用一个数组创建一个嵌套的地图类型
在这个例子中,你可以创建一个Map,key是字符串,value是地图数组。首先,使用literal语法的功能创建一个带有数组地图的Map。
mapArraysMap := map[string][]map[string]string{
"kiran": {{"id": "1"}, {"name": "kiran"}},
"john": {{"id": "2"}, {"name": "kiran"}},
}
它创建了一个Map ,其中key 是一个字符串,分配给一个数组地图的值。添加和删除元素的方式与普通地图相同。
下面是一个Map与数组地图的完整例子
package main
import (
"fmt"
)
func main() {
//Create a Map with array of map
mapArraysMap := map[string][]map[string]string{
"kiran": {{"id": "1"}, {"name": "kiran"}},
"john": {{"id": "2"}, {"name": "kiran"}},
}
fmt.Println(mapArraysMap)
fmt.Println("Original length: ", len(mapArraysMap))
//Adding an Array of Map values to map
mapArraysMap["frank"] = []map[string]string{{"id": "2"}, {"name": "kiran"}}
fmt.Println(mapArraysMap)
fmt.Println("length: ", len(mapArraysMap))
//Delete entry from Map
delete(mapArraysMap, "frank")
fmt.Println("length: ", len(mapArraysMap))
}
输出:
map[3:Gef 1:ram 2:arun]
map[kiran:[map[id:1] map[name:kiran]] john:[map[id:2] map[name:kiran]]]
Original length: 2
map[john:[map[id:2] map[name:kiran]] frank:[map[id:2] map[name:kiran]] kiran:[map[id:1] map[name:kiran]]]
length: 3
length: 2
如何从Map转换Slice/Array?
Slice 是一个动态数组,其长度在运行时增长。map 是一个具有键和值对的集合。
map 在搜索、添加和删除方面的性能很好,但在迭代方面却不好。有时,我们需要将一个Slice的字符串转换为MAP。然而,没有标准的API函数可以将Slice字符串转换为Map。
声明并初始化了一个slice ,其中有如下的字符串字样
//create a slice with string literal
countries := []string{"india", "USA", "UK", "France"}
同时创建一个Map ,键为整数,值为字符串。用简单的for循环或带范围的循环来迭代slice 。
下面是一个完整的例子
package main
import (
"fmt"
)
func main() {
//create a slice with string literal
countries := []string{"india", "USA", "UK", "France"}
fmt.Println(countries)
// Create and initilize a Map with make function
countriesMap := make(map[int]string)
// Iterate Slice
for i := 0; i < len(countries); i++ {
countriesMap[i] = countries[i]
}
fmt.Println(countriesMap)
}
输出:
[india USA UK France]
map[2:UK 3:France 0:india 1:USA]
由于Map 是一个无序的数据结构,当你多次运行上述程序时,显示数据的顺序可能会改变。
如何将地图转换为数组的键/值/项片?
通常,我们需要从一个Map 类型中检索键、值或两者。
例如,我们有一个Map ,其中的键和值是字符串类型。
下面的程序讲述了以下内容:
- 从Map中获取键的片断。
- 来自Map的值的数组。
- 从Map中获取项目的键值切片。
下面是Convert Map to Key/values/items Slices example 的代码。
package main
import (
"fmt"
)
func main() {
// Create and intilize map with string literals - First Name - Last Name
names := map[string]string{
"kiran": "Babu",
"John": "Frank",
"Silver": "Stallin",
}
fmt.Println("Map ", names)
fmt.Println("Key value ", names)
// Retrieve keys of slice from Map
keys := []string{}
for key, _ := range names {
keys = append(keys, key)
}
fmt.Println("Keys ", keys)
// Retrieve values of slice from Map
values := []string{}
for _, value := range names {
values = append(values, value)
}
fmt.Println("Values ", values)
// Retrieve slice of key-value pairs from Map
items := [][]string{}
for key, value := range names {
items = append(items, []string{key, value})
}
fmt.Println("Values ", items)
}
输出:
Map map[kiran:Babu John:Frank Silver:Stallin]
Key value map[Silver:Stallin kiran:Babu John:Frank]
Keys [Silver kiran John]
Values [Frank Stallin Babu]
Values [[Silver Stallin] [kiran Babu] [John Frank]]
将两个或多个地图合并成一个地图
在Golang中没有标准的函数用于merge 或join 地图。我们必须写一个自定义函数来将多个地图merge 为一个单一的地图。
结果地图对于一个给定的键可能有多个值,所以值应该被声明为slice ,然后输出map[string][]string类型的地图。
下面是地图合并的过程
- 迭代地图
- 对于每一次迭代,将源地图中的每个值追加到输出地图中给定键的分片上
- 一旦分片地图被追加,我们必须把这个分片分配给输出地图的给定键值
- 这个过程允许输出地图中出现重复的元素
下面是一个完整的地图合并的例子
package main
import (
"fmt"
)
func main() {
m1 := map[string]string{"k1": "v1"}
m2 := map[string]string{"k2": "v2"}
m3 := map[string]string{"k1": "v3"}
output := mergeMaps(m1, m2, m3)
fmt.Println(output)
}
func mergeMaps(maps ...map[string]string) map[string][]string {
result := map[string][]string{}
for _, m := range maps {
for k, v := range m {
result[k] = append(result[k], v)
}
}
return res
}
上述程序的输出
map[id_1:[val_1 val_3] id_2:[val_2]]
如何检查地图的键和值的类型 - Reflection API
我们可以使用标准反射API获得地图的键和值的类型。
reflect.TypeOf() function返回给定变量的动态类型。如果给定的变量是nil 接口,它将返回nil 。
reflect.TypeOf().key() function 返回地图键的数据类型。如果给定的类型不是 ,它会抛出一个紧急错误。map
reflect.TypeOf().elem() function 返回地图值的数据类型。如果给定的类型不是 ,它会抛出一个恐慌性错误。map
下面是一个完整的例子
package main
import (
"fmt"
"reflect"
)
func main() {
var mymap map[string]int
fmt.Println("Map Type: ", reflect.TypeOf(mymap))
fmt.Println("Map Key Type: ", reflect.TypeOf(mymap).Key())
fmt.Println("Map Value Type: ", reflect.TypeOf(mymap).Elem())
mapArraysMap := map[string][]map[string]string{
"kiran": {{"id": "1"}, {"name": "kiran"}},
}
fmt.Println("Map Type: ", reflect.TypeOf(mapArraysMap))
fmt.Println("Map Key Type: ", reflect.TypeOf(mapArraysMap).Key())
fmt.Println("Map Value Type: ", reflect.TypeOf(mapArraysMap).Elem())
}
输出:
Map Type: map[string]int
Map Key Type: string
Map Value Type: int
Map Type: map[string][]map[string]string
Map Key Type: string
Map Value Type: []map[string]string
将Struct类型与Map转换为JSON类型
在下面给定的代码中,我们已经声明了一个struct ,其中有标准字符串对象的每个元素,除了地址元素。地址元素是一个map 的字符串。
type Employee struct {
Id string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Address map[string]string `json:"address,omitempty"`
}
将使用j将这个struct 转换为JSON 。son.MarshalIndent() function
以下是一个例子
package main
import (
"encoding/json"
"fmt"
)
// Declare Struct type
type Employee struct {
Id string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Address map[string]string `json:"address,omitempty"`
}
func main() {
// Initialized Struct and add data to it
var emp Employee
emp.Id = "1"
emp.Name = "Frank"
m := make(map[string]string)
emp.Address = m
emp.Address["city"] = "Newyork"
emp.Address["country"] = "USA"
emp.Address["zipcode"] = "92451"
var data []byte
// Convert struct to json
data, _ = json.MarshalIndent(emp, "", " ")
fmt.Println(string(data))
}
输出:
{
"id": "1",
"name": "Frank",
"address": {
"Country": "USA",
"city": "Newyork",
"zipcode": "92451"
}
}
总结
在这篇文章中,你学习了golang的地图类型,有多个例子,以及从地图到slice和array以及struct nested的转换。