こちらが問題文
A Tour of Go
Exercise: Maps
WordCount 関数を実装してみましょう。文字列 s の “word” の数のmapを戻す必要があります。 wc.Test 関数は、引数に渡した関数に対しテストスイートを実行し、成功か失敗かを結果に表示します。
strings.Fields で、何かヒントを得ることができるはずです。
package main
import (
"code.google.com/p/go-tour/wc"
)
func WordCount(s string) map[string]int {
return map[string]int{"x": 1}
}
func main() {
wc.Test(WordCount)
}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
import に "fmt"を追加して Sの中身をみてみた。
import (
"code.google.com/p/go-tour/wc"
"fmt"
)
func WordCount(s string) map[string]int {
fmt.Println(s)
return map[string]int{"x": 1}
}
....
output:
I am learning Go!
...
なるほど。
Javaぽく考えると、string sをsplit として、mapにあるかを判定し、なければ追加、あればValueを更新でいけるかな。
書いたコードがこちら
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
func WordCount(s string) map[string]int {
m := make(map[string]int)
for _, s_token := range strings.Split(s, " "){
v, ok := m[s_token]
if ok {
m[s_token]++
}else{
m[s_token] = 1
}
}
return m
}
golangは range [array] ってやると、 index, element が返ってくるので
1個目のつかわないIndexは _ で捨てて、中身だけ使ってます。
map[key] は value, ok(keyの有無)が返ってくるので
もし、keyがあればvalueを+1して、なければ1を代入しています。
これでも動くんですが、これだとJavaでしかなく、Golangぽくないので、いろいろ調べてみたところ
なんと map[key]++ これだけで、無ければ挿入、あればインクリメントしてくれるらしい
あと、Split(s, " ") = Fields.(s) らしいので変更した結果がこちら。
...
func WordCount(s string) map[string]int {
m := make(map[string]int)
for _, s_token := range strings.Fields(s){
m[s_token]++
}
return m
}
...
多少見やすくなったかな。