最高分

最高分

學習練習

簡介

映射

Elixir 中的映射是用來以鍵值對儲存資料的資料結構。在其他語言中,它們也可能被稱為關聯式陣列(PHP)、雜湊(Perl 5、Raku)或字典(Python)。

鍵和值可以是任何資料型態,但如果鍵是原子,我們就可以使用簡寫語法。存取或回傳映射時,並不保證其中項目的順序。

字面值形式

一個空的映射只要用 %{} 就能宣告。如果想在映射字面值中加入項目,有兩種形式可以用:

# If the key is an atom:
%{atom_key: 1}

# If the key is a different type:
%{1 => :atom_value}

# You can even mix these if the atom form comes second:
%{"first_form" => :a, atom_form: :b}

雖然沒有標準格式,但請選擇一致的方式來表示鍵值對字面值。

Map 模組的函式

在 Elixir 中,Map 模組 提供了許多處理映射的函式。有些 Map 模組 的函式需要傳入一個 匿名 函式,來協助轉換映射。

模組屬性作為常數

在 Elixir 中,我們可以定義模組屬性,並在函式中把它們當作常數使用。

defmodule Example do
  # Defines the attribute as the value 1
  @constant_number 1

  def example_value() do
    # Returns the value 1
    @constant_number
  end
end

用來定義模組常數時,模組屬性可以是任何能在編譯時期求值的運算式。編譯過後就無法再存取模組屬性,因為它們在編譯期間就會被展開,這與 C 這類語言中定義的巨集類似。

說明

在這個練習中,你要實作一種方法,用來追蹤你當地電動遊樂場裡最熱門遊戲的高分。

1. 定義新的高分映射

要建立新的高分映射,請定義 HighScore.new/0 函式,這個函式不接受任何引數,並回傳一個新的空高分映射。

HighScore.new()
# => %{}

2. 將玩家加入高分映射

要將玩家加入高分映射,請定義 HighScore.add_player/3,這是一個接受 3 個引數的函式:

  • 第一個引數是分數映射。
  • 第二個引數是玩家的名字,型態為字串。
  • 第三個引數是分數,型態為整數。這個引數是選用的,請把第三個引數的預設值設為 0。

請把預設的初始分數存在模組屬性裡,之後還會用到。

score_map = HighScore.new()
# => %{}
score_map = HighScore.add_player(score_map, "Dave Thomas")
# => %{"Dave Thomas" => 0}
score_map = HighScore.add_player(score_map, "José Valim", 486_373)
# => %{"Dave Thomas" => 0, "José Valim"=> 486_373}

3. 從分數映射中移除玩家

要從高分映射中移除玩家,請定義 HighScore.remove_player/2,它接受 2 個引數:

  • 第一個引數是分數映射。
  • 第二個引數是玩家的名字,型態為字串。
score_map = HighScore.new()
# => %{}
score_map = HighScore.add_player(score_map, "Dave Thomas")
# => %{"Dave Thomas" => 0}
score_map = HighScore.remove_player(score_map, "Dave Thomas")
# => %{}

4. 重設玩家的分數

要重設玩家的分數,請定義 HighScore.reset_score/2,它接受 2 個引數:

  • 第一個引數是分數映射。
  • 第二個引數是玩家的名字,型態為字串,也就是你想重設分數的玩家。

如果玩家還沒有分數,這個函式也應該能正常運作。

score_map = HighScore.new()
# => %{}
score_map = HighScore.add_player(score_map, "José Valim", 486_373)
# => %{"José Valim"=> 486_373}
score_map = HighScore.reset_score(score_map, "José Valim")
# => %{"José Valim"=> 0}

5. 更新玩家的分數

要透過在先前分數上加分來更新玩家的分數,請定義 HighScore.update_score/3,它接受 3 個引數:

  • 第一個引數是分數映射。
  • 第二個引數是玩家的名字,型態為字串,也就是你想更新分數的玩家。
  • 第三個引數是你想加到已儲存高分上的分數。

如果玩家先前沒有分數,這個函式也應該能正常運作,請假設先前的分數是 0。

score_map = HighScore.new()
# => %{}
score_map = HighScore.add_player(score_map, "José Valim", 486_373)
# => %{"José Valim"=> 486_373}
score_map = HighScore.update_score(score_map, "José Valim", 5)
# => %{"José Valim"=> 486_378}

6. 取得玩家陣列

要取得玩家陣列,請定義 HighScore.get_players/1,它接受 1 個引數:

  • 第一個引數是分數映射。
score_map = HighScore.new()
# => %{}
score_map = HighScore.add_player(score_map, "Dave Thomas", 2_374)
# => %{"Dave Thomas" => 2_374}
score_map = HighScore.add_player(score_map, "José Valim", 486_373)
# => %{"Dave Thomas" => 2_374, "José Valim"=> 486_373}
HighScore.get_players(score_map)
# => ["Dave Thomas", "José Valim"]
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Elixir Exercism

準備好開始 最高分 了嗎?

註冊 Exercism,透過 58 個概念168 個練習 和真人引導來學習並精通 Elixir,全部免費。