Sfoglia il codice sorgente

add 08.2.md 08.3.md 08.4.md 08.5.md 08.6.md

chidouhu 12 anni fa
parent
commit
aaee8481fb

+ 72 - 0
eBook/08.2.md

@@ -0,0 +1,72 @@
+#8.2 删除元素
+测试map1中是否存在key1:
+
+在例子8.1中,我们已经见过可以使用val1 = map1[key1]的方法获取key1对应的值val1。如果map中不存在key1,val1就是一个值类型的空值。
+
+这就会给我们带来困惑了:现在我们没法区分到底是key1不存在还是它对应的value就是空值。
+
+为了解决这个问题,我们可以这么用: val1, isPresent = map1[key1]
+
+isPresent返回一个bool值:如果key1存在于map1,val1就是key1对应的value值,并且isPresent为true;如果key1不存在,val1就是一个空值,并且isPresent会返回false。
+
+如果你只是想判断某个key是否存在而不关心它对应的值到底是多少,你可以这么做:
+
+	_, ok := map1[key1] // 如果key1存在则ok == true,否在ok为false
+
+或者和if混合使用:
+
+	if _, ok := map1[key1]; ok {
+		// ...
+	}
+
+从map1中删除key1:
+
+直接: delete(map1, key1)
+
+如果key1不存在,该操作不会产生错误。
+
+示例 8.4 [map_testelement.go](exmaples/chapter_8/map_testelement.go)
+
+    package main
+    import "fmt"
+    
+    func main() {
+    	var value int
+    	var isPresent bool
+    
+    	map1 := make(map[string]int)
+    	map1["New Delhi"] = 55
+    	map1["Beijing"] = 20
+    	map1["Washington"] = 25
+    	value, isPresent = map1["Beijing"]
+    	if isPresent {
+    		fmt.Printf("The value of \"Beijin\" in map1 is: %d\n", value)
+    	} else {
+    		fmt.Printf("map1 does not contain Beijing")
+    	}
+    
+    	value, isPresent = map1["Paris"]
+    	fmt.Printf("Is \"Paris\" in map1 ?: %t\n", isPresent)
+    	fmt.Printf("Value is: %d\n", value)
+    
+    	// delete an item:
+    	delete(map1, "Washington")
+    	value, isPresent = map1["Washington"]
+    	if isPresent {
+    		fmt.Printf("The value of \"Washington\" in map1 is: %d\n", value)
+    	} else {
+    		fmt.Println("map1 does not contain Washington")
+    	}
+    }
+
+输出结果:
+
+	The value of "Beijing" in map1 is: 20
+	Is "Paris" in map1 ?: false
+	Value is: 0
+	map1 does not contain Washington
+
+##链接
+- [目录](directory.md)
+- 上一节:[声明,初始化和make](08.1.md)
+- 下一节:[for循环构造方法](08.3.md)

+ 59 - 0
eBook/08.3.md

@@ -0,0 +1,59 @@
+#8.3 for循环构造方法
+可以使用for循环构造map:
+
+	for key, value := range map1 {
+		...
+	}
+
+第一个返回值key是map中的key值,第二个返回值则是该key对应的value值;这两个都是仅for循环内部可见的局部变量。其中第一个返回值key值是一个可选元素。如果你只关心值,可以这么使用
+
+	for _, value := range map1 {
+		...
+	}
+
+如果只想获取key,你可以这么使用:
+
+	for key := range map1 {
+		fmt.Printf("key is: %d\n", key)
+	}
+
+示例 8.5 [maps_forrange.go](exmaples/chapter_8/maps_forrange.go)
+
+    package main
+    import "fmt"
+    
+    func main() {
+    	map1 := make(map[int]float32)
+    	map1[1] = 1.0
+    	map1[2] = 2.0
+    	map1[3] = 3.0
+    	map1[4] = 4.0
+    	for key, value := range map1 {
+    		fmt.Printf("key is: %d - value is: %f\n", key, value)
+    	}
+    }
+
+输出结果:
+
+	key is: 3 - value is: 3.000000
+	key is: 1 - value is: 1.000000
+	key is: 4 - value is: 4.000000
+	key is: 2 - value is: 2.000000
+
+注意到map不是按照key的顺序排列的,也不是按照value的序排列的。
+
+问题 8.1: 下面这段代码的输出是什么?
+
+	capitals := map[string] string {"France":"Paris", "Italy":"Rome", "Japan":"Tokyo" }
+	for key := range capitals {
+		fmt.Println("Map item: Capital of", key, "is", capitals[key])
+	}
+
+练习 8.1: map_days.go
+
+创建一个map来保存每周7天的名字,将它们打印出来并且测试是否存在tuesday和hollyday。
+
+##链接
+- [目录](directory.md)
+- 上一节:[删除元素](08.2.md)
+- 下一节:[maps分片](08.4.md)

+ 37 - 0
eBook/08.4.md

@@ -0,0 +1,37 @@
+#8.3 map分片
+假设我们想获取一个map的分片,我们必须使用两次make()方法,第一次分配slice,第二次分配slice的每个map元素(参见下面的例子8.3)。
+
+示例 8.3 [maps_forrange.go](exmaples/chapter_8/maps_forrange.go)
+
+    package main
+    import "fmt"
+    
+    func main() {
+    	// Version A:
+    	items := make([]map[int]int, 5)
+    	for i:= range items {
+    		items[i] = make(map[int]int, 1)
+    		items[i][1] = 2
+    	}
+    	fmt.Printf("Version A: Value of items: %v\n", items)
+    
+    	// Version B: NOT GOOD!
+    	items2 := make([]map[int]int, 5)
+    	for _, item := range items2 {
+    		item = make(map[int]int, 1) // item is only a copy of the slice element.
+    		item[1] = 2 // This 'item' will be lost on the next iteration.
+    	}
+    	fmt.Printf("Version B: Value of items: %v\n", items2)
+    }
+
+输出结果:
+
+	Version A: Value of items: [map[1:2] map[1:2] map[1:2] map[1:2] map[1:2]]
+	Version B: Value of items: [map[] map[] map[] map[] map[]]
+
+需要注意的是,应当像A版本那样通过索引使用slice的map项。在B版本中获得的项只是map值的一个拷贝而已,所以真正的map元素没有得到初始化。
+
+##链接
+- [目录](directory.md)
+- 上一节:[for循环构造方法](08.3.md)
+- 下一节:[map排序](08.5.md)

+ 59 - 0
eBook/08.5.md

@@ -0,0 +1,59 @@
+#8.5 map排序
+map默认是无序的,不管是按照key还是按照value默认都不排序(参见8.3节)
+
+如果你想为map排序,需要将key(或者value)拷贝到一个slice,再对slice排序(使用sort包,参见7.6.6),然后可以使用slice的for-range方法打印出所有的key和value。
+
+下面有一个示例:
+
+示例 8.6 [sort_map.go](exmaples/chapter_8/sort_map.go)
+    
+    // the telephone alphabet:
+    package main
+    import (
+    	"fmt"
+    	"sort"
+    )
+    
+    var (
+    	barVal = map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
+    							"delta": 87, "echo": 56, "foxtrot": 12,
+    							"golf": 34, "hotel": 16, "indio": 87,
+    							"juliet": 65, "kili": 43, "lima": 98}
+    )
+    
+    func main() {
+    	fmt.Println("unsorted:")
+    	for k, v := range barVal {
+    		fmt.Printf("Key: %v, Value: %v / ", k, v)
+    	}
+    	keys := make([]string, len(barVal))
+    	i := 0
+    	for k, _ := range barVal {
+    		keys[i] = k
+    	i++
+    	}
+    	sort.Strings(keys)
+    	fmt.Println()
+    	fmt.Println("sorted:")
+    	for _, k := range keys {
+    		fmt.Printf("Key: %v, Value: %v / ", k, barVal[k])
+    	}
+    }
+
+输出结果:
+	unsorted:
+	Key: bravo, Value: 56 / Key: echo, Value: 56 / Key: indio, Value: 87 / Key: juliet, Value: 65 / Key: alpha, Value: 34 / Key: charlie, Value: 23 / Key: delta, Value: 87 / Key: foxtrot, Value: 12 / Key: golf, Value: 34 / Key: hotel, Value: 16 / Key: kili, Value: 43 / Key: lima, Value: 98 / 
+	sorted:
+	Key: alpha, Value: 34 / Key: bravo, Value: 56 / Key: charlie, Value: 23 / Key: delta, Value: 87 / Key: echo, Value: 56 / Key: foxtrot, Value: 12 / Key: golf, Value: 34 / Key: hotel, Value: 16 / Key: indio, Value: 87 / Key: juliet, Value: 65 / Key: kili, Value: 43 / Key: lima, Value: 98 / [[email protected] go]$ sz -be sort_map.go 
+
+但是如果你想要一个排序的列表你最好使用结构体slice,这样会更有效:
+
+	type struct {
+		key string
+		value int
+	}
+
+##链接
+- [目录](directory.md)
+- 上一节:[maps分片](08.4.md)
+- 下一节:[倒置map](08.6.md)

+ 44 - 0
eBook/08.6.md

@@ -0,0 +1,44 @@
+#8.6 倒置map
+这里倒置是指调换key和value。如果map的值类型可以作为key且所有的value是唯一的,那么通过下面的方法可以简单的做到倒置:
+
+示例 8.7 [invert_map.go](exmaples/chapter_8/invert_map.go)
+
+	package main
+	import (
+		"fmt"
+	)
+
+	var (
+		barVal = map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
+								"delta": 87, "echo": 56, "foxtrot": 12,
+								"golf": 34, "hotel": 16, "indio": 87,
+								"juliet": 65, "kili": 43, "lima": 98}
+	)
+
+	func main() {
+		invMap := make(map[int]string, len(barVal))
+		for k, v := range barVal {
+			invMap[v] = k
+		}
+		fmt.Println("inverted:")
+		for k, v := range invMap {
+			fmt.Printf("Key: %v, Value: %v / ", k, v)
+		}
+		fmt.Println()
+	}
+  
+输出结果:
+
+	inverted:
+	Key: 34, Value: golf / Key: 23, Value: charlie / Key: 16, Value: hotel / Key: 87, Value: delta / Key: 98, Value: lima / Key: 12, Value: foxtrot / Key: 43, Value: kili / Key: 56, Value: bravo / Key: 65, Value: juliet /
+
+如果原始value值不唯一那么这么做肯定会出错;为了保证不出错,当遇到不唯一的key时应当立刻停止,这样可能会导致没有包含原map的所有键值对!一种解决方法就是仔细检查唯一性并且使用多值map,比如使用`map[int][]string`类型。
+
+练习 8.2: map_drinks.go
+
+构造一个将英文饮料名映射为法语(或者任意你的母语)的集合;先打印所有的饮料,然后打印原名和翻译后的名字。接下来按照英文名排序后再打印出来。
+
+##链接
+- [目录](directory.md)
+- 上一节:[map排序](08.5.md)
+- 下一节:[包](09.0.md)

+ 23 - 0
eBook/examples/chapter_8/invert_map.go

@@ -0,0 +1,23 @@
+package main
+import (
+    "fmt"
+)
+
+var (
+    barVal = map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
+                            "delta": 87, "echo": 56, "foxtrot": 12,
+                            "golf": 34, "hotel": 16, "indio": 87,
+                            "juliet": 65, "kili": 43, "lima": 98}
+)
+
+func main() {
+    invMap := make(map[int]string, len(barVal))
+    for k, v := range barVal {
+        invMap[v] = k
+    }
+    fmt.Println("inverted:")
+    for k, v := range invMap {
+        fmt.Printf("Key: %v, Value: %v / ", k, v)
+    }
+    fmt.Println()
+}

+ 31 - 0
eBook/examples/chapter_8/map_testelement.go

@@ -0,0 +1,31 @@
+package main
+import "fmt"
+
+func main() {
+    var value int
+    var isPresent bool
+
+    map1 := make(map[string]int)
+    map1["New Delhi"] = 55
+    map1["Beijing"] = 20
+    map1["Washington"] = 25
+    value, isPresent = map1["Beijing"]
+    if isPresent {
+        fmt.Printf("The value of \"Beijin\" in map1 is: %d\n", value)
+    } else {
+        fmt.Printf("map1 does not contain Beijing")
+    }
+
+    value, isPresent = map1["Paris"]
+    fmt.Printf("Is \"Paris\" in map1 ?: %t\n", isPresent)
+    fmt.Printf("Value is: %d\n", value)
+
+    // delete an item:
+    delete(map1, "Washington")
+    value, isPresent = map1["Washington"]
+    if isPresent {
+        fmt.Printf("The value of \"Washington\" in map1 is: %d\n", value)
+    } else {
+        fmt.Println("map1 does not contain Washington")
+    }
+}

+ 13 - 0
eBook/examples/chapter_8/maps_forrange.go

@@ -0,0 +1,13 @@
+package main
+import "fmt"
+
+func main() {
+    map1 := make(map[int]float32)
+    map1[1] = 1.0
+    map1[2] = 2.0
+    map1[3] = 3.0
+    map1[4] = 4.0
+    for key, value := range map1 {
+        fmt.Printf("key is: %d - value is: %f\n", key, value)
+    }
+}

+ 20 - 0
eBook/examples/chapter_8/slice_maps.go

@@ -0,0 +1,20 @@
+package main
+import "fmt"
+
+func main() {
+    // Version A:
+    items := make([]map[int]int, 5)
+    for i:= range items {
+        items[i] = make(map[int]int, 1)
+        items[i][1] = 2
+    }
+    fmt.Printf("Version A: Value of items: %v\n", items)
+
+    // Version B: NOT GOOD!
+    items2 := make([]map[int]int, 5)
+    for _, item := range items2 {
+        item = make(map[int]int, 1) // item is only a copy of the slice element.
+        item[1] = 2 // This 'item' will be lost on the next iteration.
+    }
+    fmt.Printf("Version B: Value of items: %v\n", items2)
+}

+ 32 - 0
eBook/examples/chapter_8/sort_map.go

@@ -0,0 +1,32 @@
+// the telephone alphabet:
+package main
+import (
+    "fmt"
+    "sort"
+)
+
+var (
+    barVal = map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
+                            "delta": 87, "echo": 56, "foxtrot": 12,
+                            "golf": 34, "hotel": 16, "indio": 87,
+                            "juliet": 65, "kili": 43, "lima": 98}
+)
+
+func main() {
+    fmt.Println("unsorted:")
+    for k, v := range barVal {
+        fmt.Printf("Key: %v, Value: %v / ", k, v)
+    }
+    keys := make([]string, len(barVal))
+    i := 0
+    for k, _ := range barVal {
+        keys[i] = k
+        i++
+    }
+    sort.Strings(keys)
+    fmt.Println()
+    fmt.Println("sorted:")
+    for _, k := range keys {
+        fmt.Printf("Key: %v, Value: %v / ", k, barVal[k])
+    }
+}