Os mapas em Elixir são a estrutura de dados para armazenar informações em pares chave-valor. Em outras linguagens, eles também podem ser conhecidos como arrays associativos (PHP), hashes (Perl 5, Raku) ou dicionários (Python).
As chaves e os valores podem ser de qualquer tipo de dados, mas se a chave for um átomo podemos usar uma sintaxe abreviada. Os mapas não garantem a ordem das suas entradas quando acessadas ou retornadas.
Um mapa vazio é simplesmente declarado com %{}. Se quisermos adicionar itens a um mapa literal, podemos usar duas formas:
# 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}
Embora não haja um formato canônico, escolha uma forma consistente de representar os pares chave-valor literais.
O Elixir oferece muitas funções para trabalhar com mapas no módulo Map. Algumas funções do módulo Map exigem que uma função anônima seja passada para ajudar na transformação do mapa.
Em Elixir, podemos definir atributos de módulo que podem ser usados como constantes nas nossas funções.
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
Quando usados para definir constantes de módulo, os atributos podem ser qualquer expressão que possa ser avaliada em tempo de compilação. Depois da compilação, os atributos de módulo não são acessíveis, já que são expandidos durante a compilação, de forma semelhante às macros definidas em linguagens como C.
Neste exercício, você vai implementar uma forma de acompanhar as pontuações mais altas do jogo mais popular do fliperama da sua região.
Para criar um novo mapa de pontuações, defina a função HighScore.new/0, que não recebe nenhum argumento e retorna um mapa de pontuações novo e vazio.
HighScore.new()
# => %{}
Para adicionar um jogador ao mapa de pontuações, defina HighScore.add_player/3, uma função que recebe 3 argumentos:
Guarde a pontuação inicial padrão em um atributo de módulo. Ela vai ser necessária de novo.
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}
Para remover um jogador do mapa de pontuações, defina HighScore.remove_player/2, que recebe 2 argumentos:
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")
# => %{}
Para redefinir a pontuação de um jogador, defina HighScore.reset_score/2, que recebe 2 argumentos:
A função também deve funcionar se o jogador não tiver uma pontuação.
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}
Para atualizar a pontuação de um jogador somando à pontuação anterior, defina HighScore.update_score/3, que recebe 3 argumentos:
A função também deve funcionar se o jogador não tiver uma pontuação anterior: considere que a pontuação anterior é 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}
Para obter uma lista de jogadores, defina HighScore.get_players/1, que recebe 1 argumento:
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"]
Crie sua conta no Exercism para aprender e dominar Elixir com 58 conceitos168 exercícios e mentoria humana de verdade, tudo de graça.