學習軌道
/
Go
Go
/
練習
/
批發商店
批發商店

批發商店

學習練習

簡介

在 Go 裡,map 是一種內建的資料型態,用來把鍵對應到值。 在其他程式語言中,你可能已經熟悉類似的概念,例如字典、雜湊表、鍵值儲存或關聯式陣列。

以語法來說,map 看起來像這樣:

map[KeyType]ElementType

另外也要知道,每個鍵都是唯一的,也就是說,對同一個鍵指定兩次值,會覆寫掉該鍵原本的值。

要建立 map,可以這樣做:

  // 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 map 中,回傳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 map 中,回傳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。
  • 否則,回傳帳單中該商品的數量和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,全部免費。