如何使用Common Lisp中的DO宏编写MEMBER函数?

时间:2017-04-07 16:52:50

标签: lisp common-lisp

我正在尝试创建一个像Common Lisp中的MEMBER函数一样的函数。 所以,我想让这个函数像这样工作:

(my-member 2 '(1 4 5 5 3 2 5 6 9))
=> (2 5 6 9)

这与MEMBER功能的工作方式完全相同。;

(member 2 '(1 4 5 5 3 2 5 6 9))
=> (2 5 6 9)

条件是我应该使用' DO'宏来做这个功能。 这是我为编写此函数而编写的代码:

(defun my-member (item x)
  "This function works like MEMBER function."
  (do ((z x (rest z))                
       (e (first x) (first z)))
      (:when (equal item (first z))      
             (return z)))) 

但它不起作用..

(my-member 2 '(3 4 5 2 1 1))
-> (3 4 5 2 1 1)

我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:3)

以下是使用do的正确方法:

(do ((var 0 (1+ var))
     (lst '() (cons var lst)))
    ((= var 5) lst)))
; ==> (4 3 2 1 0)

因此,varlst都是初始化为0()的变量,并且在每次迭代后,变量都设置为(1+ var)和{{1} }。

决定何时停止的内容是(cons var lst)变为非零,当发生这种情况时,整个(= var 5)形式的结果为do。这是lst的第二部分,也是最后一部分,因为我没有提供正文。

您只能使用一个变量和第二个具有结束条件的部分来构建do 函数的等效项,而member的结果应该是什么。祝你好运!