现象:
从一列表中,查询一子列表(用 remove-if or remove-if-not) ,然后遍历排序子列表,再处理子列表中的数据,同时需要从原始列表中查找(find)数据。
因为子列表的数据是从原始列表中提取出来的,所以子列表是原列表的子集,find操作肯定可以成功,但却发现有有find结果为NIL现象。
结论:
一番调试折腾之后发现:sort操作破坏了原列表的结构。猜测原因是子列表是通过原列表得到的,两者可能共用了部分数据结构,导致看似无关的lst2却影响到了了lst。通过将lst2 copy之后再sort,解决此问题。
教训:
sort是破坏性操作,在不确定其参数被破坏影响的情况下,最好对参数执行copy-list,生成副本数据。
简化代码:
(defun test-1 nil
(let ((lst '(1 2 3 4)))
(let ((lst2 (remove-if (lambda (x) (member x (list 2 3))) lst)))
;(sort lst2 #'>)
(print (sort (copy-list lst2) #'>))
(unless (find 4 lst)
(print "not found 4")
(print lst)))))