common lisp 里的几个操作符(2)
集合 (Set)
member 函数
默认使用 eql比较对象,可传入关键字参数 :test,作为比较的函数。关键字参数 :key,指定在每个元素上应用这个函数。
> (member 2 '((1) (2)) :test #'equal :key #'car) ((2))
直接找出满足条件的元素
> (member-if #'oddp '(2 3 4)) (3 4)
函数 adjoin
像是条件式的 cons
。它接受一个对象及一个列表,如果对象还不是列表的成员,才构造对象至列表上。
> (adjoin 'b '(a b c)) (A B C) > (adjoin 'z '(a b c)) (Z A B C)
并集、交集 以及差集。 union
、 intersection
以及 set-difference
。
> (union '(a b c) '(c b s)) (A C B S) > (intersection '(a b c) '(b b c)) (B C) > (set-difference '(a b c d e) '(b e)) (A C D)
序列 (Sequence)
一系列有特定顺序的对象。在 cl 中序列包括列表与向量 (vectors)
length 返回元素数目
> (length '(a b c)) 3
subseq 接受3个参数
> (subseq '(a b c d) 1 2) (B)
reverse 反转
> (reverse '(a b c)) (C B A)
排序 sort
。接受一个比较函数。注意sort
会修改原序列,可以先使用 copy-list 复制。
> (sort '(0 2 1 3 8) #'>) (8 3 2 1 0)
every 与 some
> (every #'oddp '(1 3 5)) T > (some #'evenp '(1 2 3)) T > (every #'> '(1 3 5) '(0 2 4)) T
栈 (Stack)
Cons 来实现 pushdown stack 很简单。cl 提供了两个宏 push 与 pop
(push obj lst) 等同于
(setf lst (cons obj lst))
(pop lst) 等同于
(let ((x (car lst))) (setf lst (cdr lst)) x)
pushnew
宏是 push
的变种,使用了 adjoin
而不是 cons
> (let ((x '(a b))) (pushnew 'c x) (pushnew 'a x) x) (C A B)
列表的 点状表示法,只有两个元素(括号算一个整体)之间可以使用点符号。
'(a . (b . nil)) '(a . (b)) '(a b . nil) '(a b)
end