List Structures
Set Functions
alexandria:setp object &key test key ⇒ boolean
Test if object is a list containing unique elements.
(setp '(a b c)) ;⇒ T
(setp '(a b b)) ;⇒ NIL
(setp '((10 :a) (10.0 :b)) :key #'car) ;⇒ T
(setp '((10 :a) (10.0 :b)) :key #'car :test #'=) ;⇒ NIL
subsetp list1 list2 &key key test test-not ⇒ boolean
Test if every element of list1 matches an element in list2.
(subsetp '(c b a) '(a b c d)) ;⇒ T
(subsetp '(a b c d) '(c b a)) ;⇒ NIL
alexandria:set-equal list1 list2 &key test key ⇒ boolean
Test if every element in list1 matches an element in list2, and vice-versa.
(set-equal '(a b c) '(c b a)) ;⇒ T
(set-equal '(a b) '(a b c)) ;⇒ NIL
member item list &key key test test-not ⇒ tail
Similiar to find, but if the item is in the list return the tail, otherwise nil. Functional variants are member-if and member-if-not.
(member 'c '(a b c d)) ;⇒ (C D)
(member-if #'evenp '(1 2 3 4)) ;⇒ (2 3 4)
(member-if-not #'evenp '(1 2 3 4)) ;⇒ (1 2 3 4)
adjoin item list &key key test test-not ⇒ new-list
Add item to list if not already there, otherwise return original list. Use pushnew to modify the original list.
union list1 list2 &key key test test-not ⇒ result-list
To save the result in place, use alexandria:unionf.
(union '(a b c) '(f a d)) ;⇒ (A B C D F)
intersection list1 list2 &key key test test-not ⇒ result-list
Return a list that contains every element in both list1 and list2.
(intersection '(a b c) '(b c d)) ;⇒ (B C)
set-difference list1 list2 &key key test test-not ⇒ result-list
Returns a list of elements of list1 that do not appear in list2.
(set-difference '(a b c e) '(b c d)) ;⇒ (A E)
set-exclusive-or list1 list2 &key key test test-not ⇒ result-list
Returns a list of elements that appear in exactly one of list1 and list2.
(set-exclusive-or '(a b c e) '(b c d)) ;⇒ (A D E)
Tree Functions
Lists of lists.
tree-equal
Compares two trees, equal if structure is same shape and leaves are eql (or :test).
copy-tree tree ⇒ new-tree
Creates a copy of a tree of conses.
subst new old tree &key key test test-not ⇒ new-tree
Make a copy of tree with each subtree or leaf matching old replaced by new, the tree counterpart to substitute. Functional variants are subst-if and subst-if-not, called on each atomic value in the tree. The destructive version is nsubst and variants.
(subst "two" 2 '(1 (1 2) (1 (2 3)))) ;⇒ (1 (1 "two") (1 ("two" 3)))
(subst-if "one" #'(lambda (x) (equal x 1)) '(1 2 (3 2 1))) ;⇒ ("one" 2 (3 2 "one")))
sublis alist tree &key key test test-not ⇒ new-tree
Make a tree copy and substitute multiple leaves using an alist.
(sublis '((1 . "one") (2 . "two")) '(1 (1 2) (1 (2 3))))
;⇒ ("one" ("one" "two") ("one" ("two" 3))))
alexandria:flatten tree ⇒ list
Collect non-null leaves into a list.
(flatten '(1 2 (3 2 1) ((1 1 nil) (2 2)))) ;⇒ (1 2 3 2 1 1 1 2 2)
alexandria:circular-tree-p object ⇒ boolean
Test if object is a circular tree.
Property List (plist)
Lists with alternating keys and values: (:x 10 :y 20)
. Uses #'eq
for :test
, so should only use symbols as keywords.
Every symbol contains metadata on it stored as a plist:
(symbol-plist 'symbol) ;access plist of symbol
(get 'symbol 'key) ;equivalent to (getf (symbol-plist 'symbol)
(setf (get 'symbol :my-key) "information") ;set value
(remprop 'symbol 'my-key) ;remove property, same as (remf (symbol-plist 'symbol) 'my-key)
getf plist indicator &optional default ⇒ value
(getf plist :x) ;⇒ 10
(setf (getf plist :x) 30) ;⇒ 30
remf place indicator ⇒ boolean
(remf plist :x) ;⇒ T
get-properties plist indicator-list ⇒ indicator, value, tail
Used since getf can’t distinguish an absent property from nil. Returns on the first key found.
(get-properties plist '(:x :y)) ;⇒ :X, 10, (:X 10 :Y 20)
alexandria:plist-alist plist
alexandria:plist-hash-table plist &rest hash-table-initargs
alexandria:remove-from-plist plist &rest keys
alexandria:remove-from-plistf plist &rest keys
destructive
alexandria:doplist (key val plist &optional values) forms*
Association List (alist)
acons key datum alist ⇒ new-alist
Append a cons and return a new alist. To modify an alist in place, use push
.
(acons :c 3 '((:B . 2) (:A . 1))) ;⇒ ((:C . 3) (:B . 2) (:A . 1))
(push (cons :c 3) alist) ;⇒ ((:C . 3) (:B . 2) (:A . 1))
pairlis keys data &optional alist ⇒ new-alist
Pair up elements in keys and data lists to make an alist.
(pairlis '(:a :b) '(1 2)) ;⇒ ((:B . 2) (:A . 1))
assoc item alist &key key test test-not ⇒ entry
Return the alist entry whose car satisfies the test, or nil. Functional variants are assoc-if
and assoc-if-not
. rassoc
uses cdr to test.
(assoc :a '((:A . 1) (:B . 2))) ;⇒ (:A . 1)
(rassoc 1 '((:A . 1) (:B . 2))) ;⇒ (:A . 1)
(assoc-if #'evenp '((1 . :A) (2 . :B))) ;⇒ (2 . :B)
copy-alist alist ⇒ new-alist
Copies the cons cells that make up the alist structure.
alexandria:alist-plist alist
Converts an alist to a plist format.
(alist-plist '((:x . 10) (:y . 20))) ;⇒ (:x 10 :y 20)