Hash-Tabellen in Common Lisp sind Datenstrukturen zum Speichern assoziativer Daten. Sie ordnen Schlüsseln (die beliebige Objekte sein können) Werte (die beliebige Objekte sein können) zu. Andere Sprachen kennen dieses Konzept vielleicht unter Namen wie Map, Dictionary oder Hash.
Hash-Tabellen lassen sich mit der Funktion make-hash-table erstellen.
(make-hash-table) ; => #<HASH-TABLE :TEST EQL :COUNT 0 {10024AD2B3}>
(Beachte: Die gedruckte Darstellung einer Hash-Tabelle hängt von der Implementierung ab, in deiner REPL kann sie also anders aussehen.)
Um mit einem Schlüssel einen Wert aus der Hash-Tabelle zu holen, verwendest du die Funktion gethash:
*h* ; => #<HASH-TABLE :TEST EQL :COUNT 3 {10024AD2B3}>`
(gethash :foo *h*) ; => :bar
; T
gethash gibt mehrere Werte zurück, die in einem anderen Konzept erklärt werden.
Um einen Wert in eine Hash-Tabelle einzufügen, verwendest du setf zusammen mit gethash, und zwar so:
(setf (gethash :foo *hash-table*) :bar) : => :bar
Damit änderst du den Wert für den Schlüssel :foo in der Hash-Tabelle *hash-table* zu :bar.
Dabei wird der Wert zurückgegeben.
Die Verwendung von setf wird in einem anderen Konzept erklärt.
Lamont ist ein Lisp-Alien, das sein eigenes Videospiel schreiben möchte. Eine Aufgabe, bei der es deine Hilfe braucht, ist das Führen einer Highscore-Liste.
Definiere eine Funktion make-high-score-table, die keine Argumente entgegennimmt und sich zu einer neuen, leeren Hash-Tabelle auswertet:
(make-high-score-table) ; => #<HASH-TABLE :TEST EQL :COUNT 0 {1005A90103}>
Um einen Spieler zur Tabelle hinzuzufügen, definiere eine Funktion add-player, die zwei Argumente entgegennimmt:
Setze die Anfangspunktzahl des Spielers auf null.
(add-player hash-table :louis) ; => 0
(add-player hash-table :lilly) ; => 0
Um die Punktzahl für einen Spieler festzulegen, definiere eine Funktion set-score, die drei Argumente entgegennimmt:
(set-score hash-table :louis 1234) ; => 1234
Um die Punktzahl eines Spielers aus der Tabelle abzurufen, definiere eine Funktion get-score, die zwei Argumente entgegennimmt:
Diese Funktion sollte sich zu der für den Spieler gespeicherten Punktzahl auswerten.
Wenn für diesen Spieler keine Punktzahl gespeichert ist oder der Spieler noch nicht in der Tabelle steht, sollte sie sich zu 0 auswerten.
(get-score hash-table :louis) ; => 1234
(get-score hash-table :lilly) ; => 0
(get-score hash-table :not-a-character-in-this-story) ; => 0
Um einen Spieler aus der Highscore-Tabelle zu entfernen, definiere eine Funktion remove-player, die zwei Argumente entgegennimmt:
Diese Funktion sollte Fälle problemlos behandeln, in denen der Spieler noch nicht zur Tabelle hinzugefügt wurde. Wenn ein Spieler entfernt wurde, ist die Punktzahl, die man aus der Tabelle für ihn abruft, natürlich null.
(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
Melde dich bei Exercism an, um Common Lisp mit 27 Konzepte92 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.