トラック
/
Go
Go
/
演習
/
グロス商店
グロス商店

グロス商店

学習演習

はじめに

Goでは、mapはキーを値に対応付ける組み込みのデータ型です。 他のプログラミング言語では、mapと同じ概念を辞書、ハッシュテーブル、キーと値のストア、連想配列といった名前で知っているかもしれません。

構文としては、mapは次のように書きます。

map[KeyType]ElementType

また、それぞれのキーは一意であることも押さえておきましょう。つまり、同じキーに2回代入すると、そのキーに対応する値が上書きされます。

マップを作るには、次のように書きます。

  // With map literal
  foo := map[string]int{}

または

  // or with make function
  foo := make(map[string]int)

mapでできる操作をいくつか紹介します。

  // Add a value in a map with the `=` operator:
  foo["bar"] = 42
  // Here we update the element of `bar`
  foo["bar"] = 73
  // To retrieve a map value, you can use
  baz := foo["bar"]
  // To delete an item from a map, you can use
  delete(foo, "bar")

mapに存在しないキーの値を取得しようとすると、値の型のゼロ値が返ります。 ElementTypeのデフォルト値(たとえばintなら0)が有効な値である場合、これは特に混乱の元になります。 キーがmapに存在するかどうかを確認するには、次のように書きます。

  value, exists := foo["baz"]
  // If the key "baz" does not exist,
  // value: 0; exists: false

説明

友人が、Gross Storeという古い卸売店を営んでいます。 店の名前は、そこで扱う商品の数量に由来します。数量はすべてグロス単位で数えるからです。 友人は、店のために販売時点情報管理(POS)システムを実装してほしいと頼んできました。 まずは、そのプロトタイプを作りましょう。 プロトタイプでは、数量だけを記録するようにします。 参考までに、友人が単位の一覧を渡してくれました。

単位 値
quarter_of_a_dozen 3
half_of_a_dozen 6
dozen 12
small_gross 120
gross 144
great_gross 1728

1. 単位をプログラムに保存する

単位を使うには、その単位をプログラムに保存しておく必要があります。

units := Units()
fmt.Println(units)
// Output: map[...] with entries like ("dozen": 12)

2. 新しい顧客の請求書を作る

顧客のための新しい(空の)請求書を作る関数を実装します。

bill := NewBill()
fmt.Println(bill)
// Output: map[]

3. 顧客の請求書に商品を追加する

実装するには、次のようにします:

  • 与えられたunitがunitsマップにない場合は、falseを返します。
  • そうでなければ、商品名をキーとして顧客のbillに商品を追加し、trueを返します。
  • 商品がすでに請求書にある場合は、与えられたunitに対応する数量だけその数量を増やします。
bill := NewBill()
units := Units()
ok := AddItem(bill, units, "carrot", "dozen")
fmt.Println(ok)
// Output: true (since dozen is a valid unit)

戻り値の型はboolであることに注意してください。

4. 顧客の請求書から商品を削除する

実装するには、次のようにします:

  • 与えられた商品が請求書にない場合は、falseを返します。
  • 与えられたunitがunitsマップにない場合は、falseを返します。
  • 新しい数量が0未満になる場合は、falseを返します。
  • 新しい数量が0になる場合は、billから商品を完全に削除してからtrueを返します。
  • それ以外の場合は、商品の数量を減らしてtrueを返します。
bill := NewBill()
units := Units()
ok := RemoveItem(bill, units, "carrot", "dozen")
fmt.Println(ok)
// Output: false (because there are no carrots in the bill)

戻り値の型はboolであることに注意してください。

5. 顧客の請求書にある特定の商品の数量を返す

実装するには、次のようにします:

  • itemが請求書にない場合は、0とfalseを返します。
  • それ以外の場合は、billにある商品の数量とtrueを返します。
bill := map[string]int{"carrot": 12, "grapes": 3}
qty, ok := GetItem(bill, "carrot")
fmt.Println(qty)
// Output: 12
fmt.Println(ok)
// Output: true

戻り値の型はintとboolであることに注意してください。

GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Go Exercism

グロス商店を始める準備はできましたか?

Exercismに登録すれば、34個のコンセプト165個の演習、そして本物の人間によるメンタリングとともに、Goを学んでマスターできます。すべて無料です。