Lisp - Custom Equality Checks in HashTable



In LISP, hashtable is a data structure to store key-value pairs. Keys are searched based on default 'eql' method but we can use any other method as well. In this chapter, we'll check various options with custom equality checks with examples.

:test argument in make-hash-table function

:test arguments is used to specify the equality function to compare keys.

Where, common used functions are −

  • eq − to test for object identity, using same memory location.

  • eql − to test for object identity or numeric equality. Used by default.

  • equal − to test for structural equality, a deep comparison.

  • equalp − to tests for structural equality, while ignoring case and numeric type differences.

We can define custom functions as well where a custom function accepts two arguments (keys to compare) and return t if keys are equals otherwise nil.

Using String keys with default method

main.lisp

; create a hashtable
(defvar my-hash-table (make-hash-table)) 

; add key-value pairs to hash table
(setf (gethash "apple" my-hash-table) 1)
(setf (gethash "Apple" my-hash-table) 2) 

; print the value of "apple"
(print (gethash "apple" my-hash-table))

; print the value of "Apple"
(print (gethash "Apple" my-hash-table))

Output

When you execute the code, it returns the following result −

NIL
NIL

With default method, key comparison is not working.

Using String keys with equal method

main.lisp

; create a hashtable
(defvar my-hash-table (make-hash-table :test #'equal)) 

; add key-value pairs to hash table
(setf (gethash "apple" my-hash-table) 1)
(setf (gethash "Apple" my-hash-table) 2) 

; print the value of "apple"
(print (gethash "apple" my-hash-table))

; print the value of "Apple"
(print (gethash "Apple" my-hash-table))

Output

When you execute the code, it returns the following result −

1
2

With equal method, we're doing a case-sensitive comparison.

Using String keys with equalp method, a case-insensitive comparison

main.lisp

; create a hashtable
(defvar my-hash-table (make-hash-table :test #'equalp)) 

; add key-value pairs to hash table
(setf (gethash "apple" my-hash-table) 1)
(setf (gethash "Apple" my-hash-table) 2) 

; print the value of "apple"
(print (gethash "apple" my-hash-table))

; print the value of "Apple"
(print (gethash "Apple" my-hash-table))

Output

When you execute the code, it returns the following result −

2
2

With equal method, we're doing a case-insensitive comparison.

Advertisements