Em Common Lisp, as tabelas de hash são estruturas de dados para armazenar dados associativos. Fazem o mapeamento de chaves (que podem ser qualquer objeto) para valores (que podem ser qualquer objeto). Noutras linguagens, este conceito pode ser designado por mapas, dicionários ou hashes.
As tabelas de hash podem ser criadas com a função make-hash-table.
(make-hash-table) ; => #<HASH-TABLE :TEST EQL :COUNT 0 {10024AD2B3}>
(Repara que a forma como uma tabela de hash é impressa depende da implementação, por isso pode aparecer de forma diferente no teu REPL.)
Para obter um valor a partir de uma chave da tabela de hash, usas a função gethash:
*h* ; => #<HASH-TABLE :TEST EQL :COUNT 3 {10024AD2B3}>`
(gethash :foo *h*) ; => :bar
; T
A gethash devolve vários valores, que serão explicados noutro conceito.
Para inserir um valor numa tabela de hash, usas setf com gethash assim:
(setf (gethash :foo *hash-table*) :bar) : => :bar
Isto modifica o valor da chave :foo na tabela de hash *hash-table* para :bar.
A expressão devolve o valor.
A utilização de setf será explicada noutro conceito.
Lamont é um alienígena Lisp que quer escrever o seu próprio videojogo. Uma das tarefas para as quais pediu a tua ajuda é manter uma lista de recordes.
Define uma função make-high-score-table que não recebe quaisquer argumentos e que é avaliada como uma nova tabela de hash vazia:
(make-high-score-table) ; => #<HASH-TABLE :TEST EQL :COUNT 0 {1005A90103}>
Para adicionar um jogador à tabela, define uma função add-player que recebe dois argumentos:
Define a pontuação inicial do jogador como zero.
(add-player hash-table :louis) ; => 0
(add-player hash-table :lilly) ; => 0
Para definir a pontuação de um jogador, define uma função set-score que recebe três argumentos:
(set-score hash-table :louis 1234) ; => 1234
Para obter a pontuação de um jogador a partir da tabela, define uma função get-score que recebe dois argumentos:
Esta função deve ser avaliada como a pontuação guardada para o jogador.
Se não houver nenhuma pontuação guardada para esse jogador, ou se esse jogador ainda não estiver na tabela, a avaliação deve resultar em 0.
(get-score hash-table :louis) ; => 1234
(get-score hash-table :lilly) ; => 0
(get-score hash-table :not-a-character-in-this-story) ; => 0
Para remover um jogador da tabela de recordes, define uma função remove-player que recebe dois argumentos:
Esta função deve lidar sem problemas com os casos em que o jogador ainda não foi adicionado à tabela. É evidente que, depois de um jogador ser removido, se se obtiver a sua pontuação a partir da tabela, esta será zero.
(set-score hash-table :louis 1234) ; => 1234
(remove-player hash-table :louis) ; => T
(get-score hash-table :louis) ; => 0
(remove-player hash-table :not-in-the-table) ; => NIL
Inscreve-te no Exercism para aprenderes e dominares Common Lisp com 27 conceitos92 exercícios, e mentoria humana real, tudo grátis.