Go core development study notes (twenty) - two-dimensional array, map (map)

The concept of two-dimensional arrays: one-dimensional array of elements is a one-dimensional array.

var arr [4][6]int // [ [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] ]
arr [1][2] = 1
arr [2][3] = 2
arr [3][4] = 3
fmt.Println(arr) // [[0 0 0 0 0 0] [0 0 1 0 0 0] [0 0 0 2 0 0] [0 0 0 0 3 0]]

Two-dimensional array of memory analysis:
[4] [6] This matrix is a total of 24 int elements, each element int account 8bytes in the x64 computer, so the two-dimensional array occupies 24 * 8 is the space 192Bytes.
Since the four-element array 6 form a matrix, each of the first address of a 6 element array and some a [i] is the same memory address, i.e. & a [i] == & a [i] [0].

Two-dimensional array traversal

package main
import "fmt"
func main() {
	/*
	示例,初始化一个二维数组
	 */
	//写法可以省略,var arr [2][3]int = [2][3]int{{1,2,3},{4,5,6}}
	var arr = [2][3]int{{1,2,3},{4,5,6}}
	fmt.Println(arr)
	//传统遍历
	for i:=0 ; i < len(arr) ; i++ {                 //替换为len(arr)
		for j := 0 ; j < len(arr[i]) ; j++ {        //替换为len(arr[i])
			fmt.Printf("%d ",arr[i][j])
		}
	fmt.Println()
	}
	// for-range 遍历
	for i ,value1 := range arr {
		for j , value2 := range value1 {
			fmt.Printf("a[%v][%v] = %v\n",i,j,value2)
		}
	}
}

map declaration

Statement:
var <Map Name> map [<key data type>] <value data type>
Example:
var testmap Map [int] int
var testmap1 Map [int] String
var testmap2 Map [String] String
var testmap3 Map [String ] map [string] string // definition of a string type of map, each key corresponding values, is a string type of map, corresponds to nesting.

key: a variety of types, Boolean, int, float, string, ptr , channel, generally use the most is int and string, other usage is very strange.
slice, func, map can not be used as a key, because they can not use the "==" to judge.

values: may be int, string, float, struct, map (see Example 3)

★★★ and array types are not the same, the statement is not going to allocate memory map, the need to initialize the make (), can be used after the assignment and allocate memory, not the default value is 0, "", false, etc., with different map array, unordered.
Similarly python in the dictionary, the dictionary nested dictionaries, and disorderly

Example 1:

package main
import "fmt"
func main() {
	var testmap map[string]string
	fmt.Println(testmap)
}         //map[] 这个是反馈结果

Example 2:

package main
import "fmt"
func main() {
	var testmap map[string]string
	testmap["name"] = "durant"
	fmt.Println(testmap)
}         //panic: assignment to entry in nil map 因为没有分配内存

Example 3:

package main
import "fmt"
func main() {
	var testmap map[string]string
	testmap = make(map[string]string,10)
	testmap["name"] = "durant"
	fmt.Println(testmap)
}         //使用make函数分配一个10对kv的map,10这里不传参数默认为1,注意写法  返回结果map[name:durant]

Example 4:

package main
import "fmt"
func main() {
	var testmap map[string]string
	testmap = make(map[string]string,10)
	testmap["name"] = "durant"
	testmap["name"] = "james"
	testmap["name1"] = "james"
 	fmt.Println(testmap)
}          //一个map中key只能唯一,后面你会覆盖前面的;不同的key可以有同一个值 返回结果为map[name:james name1:james]

map of use:

1. () to be declared in the usage map make, and then assign:
var testmap map [String] String
testmap = the make (map [String] String, 10)
testmap [ "Key"] = "values"

2. Direct simplify this, direct statement, then the assignment:
var = testmap the make (Map [String] String, 10)
testmap [ "Key"] = "values"

3. simplified version of the above two, without using the make (), directly after the assignment statement:
var testmap = Map [String] {String "Key": "values", "key1": "values1"}
testmap [ "key2"] = "values2"

Case: Three players number is 001,002,003, each number can query their name and jersey number, each student named durant james curry, jersey number 35,23,30
The following is shorthand, much the same, the values are by[key] —> [key][key] 这种方式取值。

package main
import "fmt"
func main() {
	var nba = map[string]map[string]string{"001":{"name":"durant","num":"35"}}
	fmt.Println(nba)                                  //map[001:map[name:durant num:35]]
	fmt.Println(nba["001"])                           //map[name:durant num:35]
	fmt.Println(nba["001"]["name"])                   //durant
}

map of the CRUD
1. increase and update the map: map [key] = value, if the key does not exist increases ©, if the key is present modification (U).
See the following example

	package main
	import "fmt"
	func main() {
		var nba = map[string]map[string]string{"001":{"name":"durant","num":"35"}}
		nba["001"]["name"] = "james"
		nba["002"] = make(map[string]string,2)            //分配新的内存空间给map中key对应的值map
		nba["002"]["name"] = "durant"
		nba["002"]["num"] = "35"
		fmt.Println(nba)                                  //map[001:map[name:durant num:35]]
		fmt.Println(nba["001"])                           //map[name:durant num:35]
		fmt.Println(nba["001"]["name"])                   //james
		fmt.Println(nba["002"]["name"])                   //durant
	}

2. map of Delete: Use delete (), use to delete (<map>, "001")

	package main
	import "fmt"
	func main() {
		var nba = map[string]map[string]string{"001":{"name":"durant","num":"35"}}
		nba["001"]["name"] = "james"
		nba["002"] = make(map[string]string,2)
		nba["002"]["name"] = "durant"
		nba["002"]["num"] = "35"
		delete(nba["001"],"name")                         //删除二层key
		delete(nba,"002")                                 //删除一层key
		delete(nba,"003")                                 //不存在003的,不会报错,什么也不操作
		fmt.Println(nba)                                  //map[001:map[num:35]]
		fmt.Println(nba["001"])                           //map[num:35]
		fmt.Println(nba["001"]["name"])                   //不存在
		fmt.Println(nba["002"]["name"])                   //不存在
		nba = make(map[string]map[string]string)
		fmt.Println(nba)                                  //删除其中所有的key太麻烦,直接指向空map
	}

Details: golang does not delete all key function, use only traverse, then for deletion; make a new map points to make (), so that the original becomes rubbish is recycled gc.

3. map lookup:

package main
import "fmt"
func main() {
	var testmap map[string]string
	testmap = make(map[string]string,10)
	testmap["name"] = "james"
 	fmt.Println(testmap)
	dest_key , value := testmap["shit"]        //如果要找一个key是否存在,可以使用if <value> { "打印出对应的key",key}
	if value {
		fmt.Println("这个key存在")                         
	} else {
		fmt.Println("没找到这个key")
	}

map traversal:

Due to the complex map data types can not be used for simple traverse, can only be used for-range
this exactly like python dictionary traverse, for k, v in xxx.items ( ): ...

One map:

package main
import "fmt"
func main() {
	var testmap = map[string]string{"name1":"durant","name2":"james"}
	for k,v := range testmap{
		fmt.Printf("%v %v\n",k,v)
	}
}

//对比下python的字典
dict = {"name1":"durant","name2":"james"}
for k,v in dirt.items()
	print("%s %s\n",k,v)

Layer map, the map is, the value is one map, <one map> [<key>] [<Layer key>]

package main
import "fmt"
func main() {
	var testmap = map[string]map[string]string{"thunder":{"name1":"durant"},"lackers":{"name2":"james"}}
	for k1,v1 := range testmap {                 //先把一层的k,v拿出来,"二层的map" == "一层的v"
		fmt.Printf("%v %v\n",k1,v1)              //thunder map[name1:durant];lakers map[name2:james]
		for k2,v2 := range v1 {                  //内层循环要拿v1这个map的值,里面再对应k2,v2
			fmt.Printf("%v %v\n",k2,v2)          //name1 durant;name2 james   其实就是注意层级关系
		}
	}
	
	//map的长度统计:
	len(<map_name>) 得到的结果是里面包含多少个kv对。
	fmt.Println(len(testmap))                    //2个kv对 雷霆和湖人
	fmt.Println(len(testmap["thunder"]))         //1个kv对 球员姓名
}

map slices and add elements

Use map sections, so use the number of map can be dynamically changed to no longer consider kv limit.

Case presentation: Use the map NBA record player names and ages, player information requirements can be dynamically increased according to demand, the number of players uncertain.

package main
import "fmt"
func main() {
	/*
	使用map记录不同球队的NBA球员的姓名和年龄,要求可以根据需求动态增加球员信息,球员数不定。
	 */
	var nbaPlayer []map[string]string
	nbaPlayer = make([]map[string]string,2)          //切片类型首先要用make分配内存

	if nbaPlayer[0] == nil {
		nbaPlayer[0] = make(map[string]string,2)     //继续为map类型分配内存,所以一共需要分配两次内存
		nbaPlayer[0]["name"] = "durant"
		nbaPlayer[0]["age"] = "30"
	}
	if nbaPlayer[1] == nil {
		nbaPlayer[1] = make(map[string]string,2)     //继续为map类型分配内存,所以一共需要分配两次内存
		nbaPlayer[1]["name"] = "james"
		nbaPlayer[1]["age"] = "35"
	}

	//由于上限设置为2,所以kv对只能有两个,如果现在写nbaPlayer[2]一定会报错out of range
	//所以使用append()动态添加,先定义一个新的player,然后添加到前面就可以了
	add_nbaPlayer := map[string]string{"name":"curry","age":"29"}       //添加一个新球员,用另外一个map
	nbaPlayer = append(nbaPlayer,add_nbaPlayer)                         //append()需要赋值给原切片
	/*
	追加结果[map[age:30 name:durant] map[age:35 name:james] map[age:29 name:curry]]
	 */
	fmt.Println(nbaPlayer)
}

map sorting

  1. map itself as a dictionary is unordered.
  2. golang no method for ordering map.
  3. I want to sort key in the map of the first sort, then according to the output value of traversal key.
  4. Method Sort: map all of the key into slices, slice sort traverse sections, the output value in accordance with the key to the map
	package main
	import (
		"fmt"
		"sort"
	)
	func main() {
		/*
		1. map本身作为字典就是无序的。
		2. golang中没有针对map排序的方法。
		3. 想排序先对map中的key进行排序,然后根据key值遍历输出即可。
		4. 排序方法:map中所有的key放入切片中,对切片进行排序,遍历切片,按照key来输出map的值
		*/
		var nbaPlayers = map[int]string{30:"curry",23:"james",35:"durant",1:"mcgrady"}
		fmt.Println(nbaPlayers)
		//这样每次输出都是无序的,把所有的key添加到一个切片中
		var slice_key []int
		//使用for-range方式遍历map,取出keys和values
		for keys, _ := range nbaPlayers {
			slice_key = append(slice_key,keys)
		}
		//使用sort.Ints([]int)方法,对int型切片进行递增排列
		sort.Ints(slice_key)                   //这个方法解决了冒泡的问题,如果从大到小排列则只需用转置方法来解决
		fmt.Println(slice_key)

		//这时key已经成功取出成为切片,那么接下来要遍历切片,取出所有的value值作为map nbaPlayer的key
		for _ , v := range slice_key{
			fmt.Println(nbaPlayers[v])
		}
	}

map Details

  1. Reference type data, the map function receives modification, after the call directly change the original value of the map.

    package main
    import "fmt"
    func modify(test map[int]int) {
    	test[2] = 6                    //下标为2的数值改为6
    }
    func main() {
    	var test map[int]int
    	test = make(map[int]int,3)
    	test[0] = 3
    	test[1] = 4
    	test[2] = 5
    	modify(test)
    	fmt.Println(test)             //map[0:3 1:4 2:6] 不再是5,直接改成6了
    }
    
  2. The capacity expansion will automatically map, panic will not occur.

  3. The map value struct structure is also often used, better than the map, the structure of which can contain different types of data.

Example 1:

package main
import "fmt"
func modifyUser(users map[string]map[string]string, name string,nickName string) {
	if users[name] != nil {
		users[name]["pwd"] = "888888"
	} else {
		users[name] = make(map[string]string,2)         //嵌套map需要make()两次,外层内层都需要make()
		users[name]["nickName"] = nickName
		users[name]["pwd"] = "111111"
	}
}

func main() {
	/*
	需求:某个用户名存在,将其密码修改为"888888";
	      不存在则创建用户,包含信息nickName和pwd
	 */
	var users map[string]map[string]string
	users = make(map[string]map[string]string,2)
	modifyUser(users,"Jimmy","jim")
	fmt.Println(users)
	modifyUser(users,"Jimmy","jim")
	fmt.Println(users)
}
Published 49 original articles · won praise 18 · views 4008

Guess you like

Origin blog.csdn.net/weixin_41047549/article/details/89931693