Updating Values of Hash Table
Lisp - Modifying Hash Table Entries
Section titled “Lisp - Modifying Hash Table Entries”Hash tables are a fundamental and highly efficient data structure in Common Lisp for storing key-value pairs. This tutorial covers the standard way to add, update, and manage entries in a hash table.
Creating and Modifying a Hash Table
Section titled “Creating and Modifying a Hash Table”The primary mechanism for adding or updating a value in a hash table is the combination of (setf gethash).
(make-hash-table): Creates a new, empty hash table.(gethash key table): Retrieves the value associated withkeyfrom thetable. If the key is not found, it returnsnil.(setf (gethash key table) value): This powerful construct sets the value associated withkeytovalue. Ifkeyalready exists, its value is updated. Ifkeydoes not exist, a new entry is created.
The Importance of the :test Function
Section titled “The Importance of the :test Function”When you create a hash table, you can specify how keys are compared using the :test argument. This is crucial for correct behavior.
#'eql(default): Compares if two objects are the same. Ideal for symbols and numbers.(eql 'a 'a)is true, but(eql "a" "a")is false because they are two different string objects in memory.#'equal: Compares if two objects have the same structure and contents. This is necessary for string keys.#'eq: Likeeqlbut may not work for numbers. Compares memory location.#'equalp: A more lenient version ofequalthat ignores case in strings and numeric types.
Example 1: Using Default eql Test (for Symbols)
Section titled “Example 1: Using Default eql Test (for Symbols)”This example shows adding and updating a hash table using symbols as keys, which works perfectly with the default eql test.
main.lisp
Section titled “main.lisp”;; Create a hash table with the default test ('eql').(defvar *symbol-ages* (make-hash-table))
;; Add initial key-value pairs.(setf (gethash 'alice *symbol-ages*) 30)(setf (gethash 'bob *symbol-ages*) 45)
(format t "Initial age of Alice: ~a~%" (gethash 'alice *symbol-ages*))
;; Update an existing value.(format t "Updating Alice's age to 31...~%")(setf (gethash 'alice *symbol-ages*) 31)
(format t "Updated age of Alice: ~a~%" (gethash 'alice *symbol-ages*))
;; Add a new entry.(format t "Adding Charlie, age 25...~%")(setf (gethash 'charlie *symbol-ages*) 25)(format t "Age of Charlie: ~a~%" (gethash 'charlie *symbol-ages*))Output
Section titled “Output”Initial age of Alice: 30Updating Alice's age to 31...Updated age of Alice: 31Adding Charlie, age 25...Age of Charlie: 25Example 2: Using equal Test for String Keys
Section titled “Example 2: Using equal Test for String Keys”When using strings as keys, you must specify #'equal as the test function.
main.lisp
Section titled “main.lisp”;; Create a hash table with the 'equal' test for strings.(defvar *fruit-prices* (make-hash-table :test #'equal))
;; Add key-value pairs.(setf (gethash "apple" *fruit-prices*) 1.50)(setf (gethash "banana" *fruit-prices*) 0.75)
(format t "Initial price of an apple: $~,2f~%" (gethash "apple" *fruit-prices*))
;; Update the price of an apple.(setf (gethash "apple" *fruit-prices*) 1.75)
(format t "Updated price of an apple: $~,2f~%" (gethash "apple" *fruit-prices*))Output
Section titled “Output”Initial price of an apple: $1.50Updated price of an apple: $1.75Removing Entries
Section titled “Removing Entries”To remove an entry from a hash table, use the remhash function. It returns t if an entry was removed, and nil otherwise.
(remhash 'bob *symbol-ages*) ; => T (entry removed)(gethash 'bob *symbol-ages*) ; => NIL (no longer exists)(remhash 'dave *symbol-ages*) ; => NIL (was never there)