OR,和mapcar的结果 - lisp

Vla*_*tra 0 lisp common-lisp logical-operators

我的任务是查找列表中是否包含给定元素(非线性列表).这就是我现在写的,但是这个函数的返回值是一个列表,我真的不明白为什么.

(setq E 4)

(defun IsMember (L)
  (cond
    ((equal E L)
      T
    )

    ((atom L)
      NIL
    )

    (T
      (or (mapcar 'IsMember L))
    )
  )
)

(print (IsMember '(1 2 3 (((4) 5) 6))))
Run Code Online (Sandbox Code Playgroud)

返回值是:(NIL NIL NIL (((T) NIL) NIL)) 但它应该真正输出,T或者NIL如果E在给定列表中找不到.

Rai*_*wig 6

你的代码:

(defun is-member (l e)
  (cond

   ((equal e l)
    t)

   ((atom l)
    nil)

   (t
    (some #'(lambda (a)
              (if (equal t a) t nil))
          (mapcar #'(lambda (b) (is-member b e)) l)))))
Run Code Online (Sandbox Code Playgroud)

摆脱IF

你测试是否有东西是T然后你返回T.你可以摆脱它.

(defun is-member (l e)
  (cond

   ((equal e l)
    t)

   ((atom l)
    nil)

   (t
    (some #'(lambda (a)
              (equal t a))
          (mapcar #'(lambda (b) (is-member b e)) l)))))
Run Code Online (Sandbox Code Playgroud)

摆脱EQUAL

由于列表由T和NIL组成,因此EQUAL也可以替换

(defun is-member (l e)
  (cond

   ((equal e l)
    t)

   ((atom l)
    nil)

   (t
    (some #'identity
          (mapcar #'(lambda (b) (is-member b e)) l)))))
Run Code Online (Sandbox Code Playgroud)

摆脱MAPCAR

由于MAPCAR返回T和NIL的列表,我们也可以删除它.

结果:

(defun is-member (list e)
  (cond ((equal list e)  t)
        ((atom list)     nil)
        (t               (some (lambda (b) (is-member b e))
                               list))))
Run Code Online (Sandbox Code Playgroud)

摆脱COND条件/值对

由于COND像OR一样使用,我们可以用OR替换COND.我们不再需要条件/值对:

(defun is-member (list e)
  (or (equal list e)
      (and (consp list)
           (some (lambda (b) (is-member b e))
                 list))))
Run Code Online (Sandbox Code Playgroud)