A Tour of Goの練習問題を解説するシリーズ(3/11) – Exercise: Maps

みなさん、こんにちは。人類をGopherにしたいと考えているまるりんです。

A Tour of Goはプログラミング言語Goの入門サイトです。 このシリーズではA Tour of Goの練習問題を解説します。

今回は以下の問題を扱います。

問題
Exercise: Maps
解答
https://go.dev/play/p/9BEEj-HRXKg


この問題はUnix系のOSに慣れている方なら、文字列を単語単位で区切って、単語をキーにした連想配列を作成し、バリューを単語の出現回数にすれば良いことが直感的に分かると思います。まず、以下を見ます。

Note: このテストスイートで何を入力とし、何を期待しているかについては、golang.org/x/tour/wcを見てみてください。

以下は参照先のテストケースです。

{"I ate a donut. Then I ate another donut.", map[string]int{
    "I": 2, "ate": 2, "a": 1, "donut.": 2, "Then": 1, "another": 1,
}},

テストケースに着目すると、文、文に出現する単語、単語の出現回数を定義しています。 wc.Test()は引数として関数を取り(解答ではWordCount())、その関数に対してテストケースの英文を入力し、期待値通りの結果になるかを検証しています。 先程のテストケースですが、よく見ると「donut」ではなく「donut.」の出現回数を定義しています。そのため文を単純にスペースで分割すれば良いことが分かります。 以下の関数を用いて文字列を分割します。

strings.Fields で、何かヒントを得ることができるはずです。

文が単語単位で分割されました(「pen.」、「piano.」となっていることも分かります)。

ソース
https://go.dev/play/p/lTk4GPLQVyu

実行結果

["This" "is" "a" "pen." "This" "is" "a" "piano."]

これらを踏まえて解答を作ってみます。すべてのテストケースをパスできました。

ソース
https://go.dev/play/p/9BEEj-HRXKg

実行結果

PASS
 f("I am learning Go!") = 
  map[string]int{"Go!":1, "I":1, "am":1, "learning":1}
PASS
 f("The quick brown fox jumped over the lazy dog.") = 
  map[string]int{"The":1, "brown":1, "dog.":1, "fox":1, "jumped":1, "lazy":1, "over":1, "quick":1, "the":1}
PASS
 f("I ate a donut. Then I ate another donut.") = 
  map[string]int{"I":2, "Then":1, "a":1, "another":1, "ate":2, "donut.":2}
PASS
 f("A man a plan a canal panama.") = 
  map[string]int{"A":1, "a":2, "canal":1, "man":1, "panama.":1, "plan":1}