I want to perform (rassoc)
over a nested list like this:
(setq mlist
(list (list (cons "A" 0)
(make-hash-table))
(list (cons "B" 1)
(make-hash-table))))
Oddly enough, (find)
and (assoc)
work as expected, but (rassoc)
fails.
(format t "~A~%" (assoc "A" mlist :key #'car :test #'equal))
(format t "~A~%" (find 0 mlist :key #'cdar :test #'equal))
(format t "~A~%" (rassoc 0 mlist :key #'car :test #'equal))
The Common Lisp HyperSpec states:
The expressions
(rassoc item list :test fn)
and
(find item list :test fn :key #'cdr)
are equivalent in meaning, except when the item is
nil
ndnil
appears in place of a pair in the alist. See the function assoc.
So, given this, I wonder, is this a bug or am I just using (rassoc)
incorrectly? I'm using sbcl 2.4.0
You are using rassoc
incorrectly. rassoc
looks at the cdr
s of the entries in an alist, skipping nil
entries, and compares them (or the result of applying the key function to them) with what you want.
The cdr
s of the entries in your list are single-element lists containing a hashtable, with a key of #'car
you will be comparing against those hashtables.
You shouldn't be using rassoc
at all if what you want to do is to check against the second element of the car
s of the alist. Instead use assoc
with an appropriate key:
> (assoc "A" mlist :key #'car :test #'equal)
(("A" . 0) #<eql Hash Table{0} 82200283A3>)
> (assoc 0 mlist :key #'cdr)
(("A" . 0) #<eql Hash Table{0} 82200283A3>)