From aaee8481fb962f7a2844153c887049f6a4876e75 Mon Sep 17 00:00:00 2001 From: chidouhu Date: Tue, 26 Nov 2013 11:35:07 +0800 Subject: [PATCH] add 08.2.md 08.3.md 08.4.md 08.5.md 08.6.md --- eBook/08.2.md | 72 +++++++++++++++++++++ eBook/08.3.md | 59 +++++++++++++++++ eBook/08.4.md | 37 +++++++++++ eBook/08.5.md | 59 +++++++++++++++++ eBook/08.6.md | 44 +++++++++++++ eBook/examples/chapter_8/invert_map.go | 23 +++++++ eBook/examples/chapter_8/map_testelement.go | 31 +++++++++ eBook/examples/chapter_8/maps_forrange.go | 13 ++++ eBook/examples/chapter_8/slice_maps.go | 20 ++++++ eBook/examples/chapter_8/sort_map.go | 32 +++++++++ 10 files changed, 390 insertions(+) create mode 100644 eBook/08.2.md create mode 100644 eBook/08.3.md create mode 100644 eBook/08.4.md create mode 100644 eBook/08.5.md create mode 100644 eBook/08.6.md create mode 100644 eBook/examples/chapter_8/invert_map.go create mode 100644 eBook/examples/chapter_8/map_testelement.go create mode 100644 eBook/examples/chapter_8/maps_forrange.go create mode 100644 eBook/examples/chapter_8/slice_maps.go create mode 100644 eBook/examples/chapter_8/sort_map.go diff --git a/eBook/08.2.md b/eBook/08.2.md new file mode 100644 index 0000000..ea283be --- /dev/null +++ b/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) \ No newline at end of file diff --git a/eBook/08.3.md b/eBook/08.3.md new file mode 100644 index 0000000..3bec240 --- /dev/null +++ b/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) \ No newline at end of file diff --git a/eBook/08.4.md b/eBook/08.4.md new file mode 100644 index 0000000..abb62f1 --- /dev/null +++ b/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) \ No newline at end of file diff --git a/eBook/08.5.md b/eBook/08.5.md new file mode 100644 index 0000000..28c222e --- /dev/null +++ b/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 / [fangjun@st01-dstream-0001.st01.baidu.com go]$ sz -be sort_map.go + +但是如果你想要一个排序的列表你最好使用结构体slice,这样会更有效: + + type struct { + key string + value int + } + +##链接 +- [目录](directory.md) +- 上一节:[maps分片](08.4.md) +- 下一节:[倒置map](08.6.md) \ No newline at end of file diff --git a/eBook/08.6.md b/eBook/08.6.md new file mode 100644 index 0000000..b08c2f6 --- /dev/null +++ b/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) \ No newline at end of file diff --git a/eBook/examples/chapter_8/invert_map.go b/eBook/examples/chapter_8/invert_map.go new file mode 100644 index 0000000..69007e0 --- /dev/null +++ b/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() +} diff --git a/eBook/examples/chapter_8/map_testelement.go b/eBook/examples/chapter_8/map_testelement.go new file mode 100644 index 0000000..88449b0 --- /dev/null +++ b/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") + } +} diff --git a/eBook/examples/chapter_8/maps_forrange.go b/eBook/examples/chapter_8/maps_forrange.go new file mode 100644 index 0000000..309d0fa --- /dev/null +++ b/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) + } +} diff --git a/eBook/examples/chapter_8/slice_maps.go b/eBook/examples/chapter_8/slice_maps.go new file mode 100644 index 0000000..203b72a --- /dev/null +++ b/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) +} diff --git a/eBook/examples/chapter_8/sort_map.go b/eBook/examples/chapter_8/sort_map.go new file mode 100644 index 0000000..db34f23 --- /dev/null +++ b/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]) + } +}