Removing Values from Hash Table
Lisp - Removing Values from a Hash Table
Section titled “Lisp - Removing Values from a Hash Table”A hash table is a fundamental data structure in Lisp for storing key-value pairs, providing efficient data retrieval. In this chapter, you’ll learn the modern, idiomatic way to remove entries from a hash table in Common Lisp.
The REMHASH function
Section titled “The REMHASH function”The primary function for removing a key-value pair from a hash table is REMHASH. It takes a key and a hash table as arguments, removes the corresponding entry if it exists, and modifies the hash table in place.
(remhash key hash-table) -> generalized-boolean- key: The key of the entry you want to remove.
- hash-table: The hash table to modify.
- Return Value:
REMHASHreturnsTif an entry was found and removed, andNILotherwise.
Step-by-Step Example: Removing an Entry
Section titled “Step-by-Step Example: Removing an Entry”Let’s walk through a complete example of creating a hash table, populating it, removing an item, and verifying the result. We will use let to create a lexically scoped hash table, which is a best practice for examples to avoid polluting the global namespace.
main.lisp
Section titled “main.lisp”(let ((product-prices (make-hash-table :test #'equal))) ;; 1. Populate the hash table with some product data (setf (gethash "Laptop" product-prices) 1200) (setf (gethash "Mouse" product-prices) 25) (setf (gethash "Keyboard" product-prices) 75)
(format t "Original table: ~a~%" product-prices) (format t "Price of a Mouse before removal: $~a~%~%" (gethash "Mouse" product-prices))
;; 2. Remove the 'Mouse' entry from the hash table (let ((removed-p (remhash "Mouse" product-prices))) (if removed-p (format t "Successfully removed the 'Mouse' entry.~%") (format t "'Mouse' entry was not found.~%")))
;; 3. Verify the entry has been removed (multiple-value-bind (price found-p) (gethash "Mouse" product-prices) (format t "~%Checking for 'Mouse' after removal:~%") (if found-p (format t "Entry still exists with price: $~a~%" price) (format t "Entry for 'Mouse' no longer exists.~%")))
(format t "Final table: ~a~%" product-prices))Output
Section titled “Output”Original table: #<HASH-TABLE :TEST EQUAL :COUNT 3 {1005A...}>Price of a Mouse before removal: $25
Successfully removed the 'Mouse' entry.
Checking for 'Mouse' after removal:Entry for 'Mouse' no longer exists.Final table: #<HASH-TABLE :TEST EQUAL :COUNT 2 {1005A...}>Best Practices and Common Pitfalls
Section titled “Best Practices and Common Pitfalls”Choosing the Right :test Function
Section titled “Choosing the Right :test Function”When creating a hash table, the :test function is crucial. It determines how keys are compared.
#'eql(the default): Compares numbers of the same type and value, or the same object in memory. Good for symbols and numbers.#'equal: Compares strings by their characters, or lists and vectors by their contents. Use this for string keys.#'equalp: A more lenient version ofequalthat ignores case for strings and numeric type differences.
Correctly Checking for Key Existence
Section titled “Correctly Checking for Key Existence”gethash returns two values: the value associated with the key (or NIL if not found), and a boolean (T or NIL) indicating if the key was found. A key might exist with the value NIL, so you must check the second return value for accurate existence checks.
;; The WRONG way (fails if value is NIL)(if (gethash key table))
;; The RIGHT way(multiple-value-bind (value found-p) (gethash key table) (if found-p ;; Key was found, do something with 'value' ...))Conclusion
Section titled “Conclusion”You now know how to effectively remove entries from a Common Lisp hash table using remhash. By following modern best practices like using let for local scope, choosing the correct :test function, and properly checking return values, you can write robust and predictable code.