Function 删除nils的LISP函数

Function 删除nils的LISP函数,function,lisp,Function,Lisp,我想用LISP编写一个函数,它将完全删除列表中的所有nil。该列表可能是嵌套的,这意味着其中可以包含其他列表。例如,列表“((state L)NIL(state L R L)NIL)应转换为“((state L L)(state L R L)) 适用于您的示例: [1]> (remove-nil-recursively '((state L L L L) NIL (state L L R L) NIL)) ((STATE L L L L) (STATE L L R L)) 和嵌套列表:

我想用LISP编写一个函数,它将完全删除列表中的所有nil。该列表可能是嵌套的,这意味着其中可以包含其他列表。例如,列表“((state L)NIL(state L R L)NIL)应转换为“((state L L)(state L R L))

适用于您的示例:

[1]> (remove-nil-recursively '((state L L L L) NIL (state L L R L) NIL))
((STATE L L L L) (STATE L L R L))
和嵌套列表:

[2]> (remove-nil-recursively '(NIL (state L L nil R L) NIL))
((STATE L L R L))
但请注意:

[3]> (remove-nil-recursively '(NIL (state L L (nil) R L) NIL))
((STATE L L NIL R L))

样式为
remove if
的通用函数:

(defun remove-all (predic seq &optional res)
  (if (null seq)
      (reverse res)
      (cond ((and (not (null (car seq))) (listp (car seq)))
             (remove-all predic (cdr seq)
                         (cons (remove-all predic (car seq)) res)))
            ((funcall predic (car seq))
             (remove-all predic (cdr seq) res))
            (t (remove-all predic (cdr seq) (cons (car seq) res))))))
示例:

>  (remove-all #'null (list 1 2 'nil 3))
=> (1 2 3)
>  (remove-all #'null (list 1 2 'nil '(4 5 nil 6) 3))
=> (1 2 (4 5 6) 3)
>  (remove-all #'(lambda (x) (oddp x)) '(1 2 (3 4) 5 6 (7 8 (9 10))))
=> (2 (4) 6 (8 (10)))

Paul Graham在,p中调用这个函数(如果“prune”,则循环到子列表remove中)。49这是一个实用功能

(defun prune (test tree)
  (labels ((rec (tree acc)
              (cond
               ((null tree) (nreverse acc))
               ((consp (car tree))
                (rec (cdr tree)
                     (cons (rec (car tree) nil) acc)))
               (t (rec (cdr tree)
                       (if (funcall test (car tree))
                           acc
                         (cons (car tree) acc)))))))
    (rec tree nil)))

(prune #'evenp '(1 2 (3 (4 5) 6) 7 8 (9)))
(1 (3 (5)) 7 (9))

remove if not接受一个谓词和一个列表,并删除列表中所有不满足谓词的项,即在谓词中求值时返回nil的项。正如您所猜测的,identity返回的内容与它所需要的完全相同,因此(如果不是“identity list”,则删除列表中所有为nil的元素。

子列表中是否有
nil
s?如果是,是否也应将其删除?如果是,嵌套可以深入到多深?虽然这个代码块可能回答了这个问题,但最好您能解释一下为什么会这样做。我添加了一个简短的解释,我希望它有助于澄清。这似乎并不像问题所说的那样处理嵌套列表。
(defun prune (test tree)
  (labels ((rec (tree acc)
              (cond
               ((null tree) (nreverse acc))
               ((consp (car tree))
                (rec (cdr tree)
                     (cons (rec (car tree) nil) acc)))
               (t (rec (cdr tree)
                       (if (funcall test (car tree))
                           acc
                         (cons (car tree) acc)))))))
    (rec tree nil)))

(prune #'evenp '(1 2 (3 (4 5) 6) 7 8 (9)))
(1 (3 (5)) 7 (9))
(defun remove-if-nil (list) (remove-if-not 'identity list))