Рекорди

Рекорди

Навчальна вправа

Вступ

Мапи

Мапи в 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 аргументи:

  • Перший аргумент - мапа рахунків.
  • Другий аргумент - імʼя гравця у вигляді рядка тексту (англ. string).
  • Третій аргумент - рахунок у вигляді цілого числа. Цей аргумент необовʼязковий, тож реалізуйте третій аргумент з типовим значенням 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, щоб вивчати й опановувати Elixir, а також 58 концепцій168 вправ та справжнє наставництво від людей, і все це безкоштовно.