Common lisp Common Lisp:检查元素是否为列表成员的函数
我想做一个函数,检查元素是否是列表的成员。该列表可以包含其他列表。 这就是我到目前为止的收获:Common lisp Common Lisp:检查元素是否为列表成员的函数,common-lisp,Common Lisp,我想做一个函数,检查元素是否是列表的成员。该列表可以包含其他列表。 这就是我到目前为止的收获: (defun subl(l) (if (numberp l) (if (= l 10) (princ "Found")) (mapcar 'subl l))) 现在我搜索的号码是硬编码的,它是10。我希望以某种方式编写它,以便函数接受另一个参数(我正在搜索的数字),并在找到它时返回true或1。主要问题是我看不到控制mapcar的方法mapcar在l的
(defun subl(l)
(if (numberp l)
(if (= l 10)
(princ "Found"))
(mapcar 'subl l)))
现在我搜索的号码是硬编码的,它是10
。我希望以某种方式编写它,以便函数接受另一个参数(我正在搜索的数字),并在找到它时返回true
或1
。主要问题是我看不到控制mapcar
的方法<如果l
是一个列表,则code>mapcar在l
的每个元素上执行subl
。但是如何控制每个调用的返回值呢
我想检查每个subl
调用的返回值,如果其中一个true
或1
则返回true
或1
,直到最后一次递归调用。因此,如果元素包含在列表中,则subl
返回true
或one
,否则返回nil
有什么想法吗?
mapcar
是一种非常通用的原语,用于将函数映射到列表上。您可以使用其中一个内置的组合器,它更适合您正在尝试的操作。查看函数。mapcar
是一个非常通用的原语,用于在列表上映射函数。您可以使用其中一个内置的组合器,它更适合您正在尝试的操作。查看函数。您的函数似乎同时扮演主函数和助手的角色。这使得您的代码比必须的更难理解
想象一下你把这两者分开:
;; a predicate to check if an element is 10
(defun number10p (l)
(and (numberp l)
(= l 10)))
;; the utility function to search for 10 amongst elements
(defun sublistp (haystack)
(mapcar #'number10p haystack)))
但在这里,当您执行(sublistp'(510520))
时,您将返回(nil t nil)
。这是因为mapcar
会列出每个结果。对我来说,你似乎在描述,因为它在第一个真值处停止
(defun sublistp (haystack)
(some #'number10p haystack)))
(sublistp '(5 10 15 20)) ; ==> t
现在,为了使其适用于任何数据类型,我们更改谓词,并将其作为一个本地函数,其中包含我们正在搜索的参数:
(defun sublistp (needle haystack)
(flet ((needlep (x)
(equal x needle)))
(some #'needlep haystack)))
(sublistp '(a b) '(a b c (a b) d e f)) ; ==> t
您还可以使用以下匿名谓词执行此操作:
(defun sublistp (needle haystack)
(some #'(lambda (x)
(equal x needle))
haystack))
该函数的一个实现是,除了它将匹配作为真值返回外。这没关系,因为在CL
中除了nil
以外的任何内容都是正确的:
(member 10 '(5 10 15 20)) ; ==> (10 15 20)
编辑
您评论了一个不同的答案,要求您使用mapcar
,在这种情况下,将其与append
一起使用,以获得所有匹配项的列表,并检查列表中的元素是否大于0:
(defun sublistp (needle haystack)
(flet ((needle-check (x)
(if (equal x needle) '(t) nil)))
(< 0 (length
(apply #'append
(mapcar #'needle-check haystack))))))
(defun子列表(针式草垛)
(针检查(x)
(如果(等于x针)’(t)无)
(<0(长度
(应用#'附加)
(mapcar#“针检干草堆(#)()(#))))
它的工作原理是,对于每个匹配项,您将得到一个包含一个元素的列表,对于每个不匹配项,您将得到一个空列表。添加列表时,如果没有匹配项,则会得到空列表。对于所有其他结果,您有一个匹配项。这不是一个非常有效的实现。您的函数似乎同时扮演主函数和助手的角色。这使得您的代码比必须的更难理解 想象一下你把这两者分开:
;; a predicate to check if an element is 10
(defun number10p (l)
(and (numberp l)
(= l 10)))
;; the utility function to search for 10 amongst elements
(defun sublistp (haystack)
(mapcar #'number10p haystack)))
但在这里,当您执行(sublistp'(510520))
时,您将返回(nil t nil)
。这是因为mapcar
会列出每个结果。对我来说,你似乎在描述,因为它在第一个真值处停止
(defun sublistp (haystack)
(some #'number10p haystack)))
(sublistp '(5 10 15 20)) ; ==> t
现在,为了使其适用于任何数据类型,我们更改谓词,并将其作为一个本地函数,其中包含我们正在搜索的参数:
(defun sublistp (needle haystack)
(flet ((needlep (x)
(equal x needle)))
(some #'needlep haystack)))
(sublistp '(a b) '(a b c (a b) d e f)) ; ==> t
您还可以使用以下匿名谓词执行此操作:
(defun sublistp (needle haystack)
(some #'(lambda (x)
(equal x needle))
haystack))
该函数的一个实现是,除了它将匹配作为真值返回外。这没关系,因为在CL
中除了nil
以外的任何内容都是正确的:
(member 10 '(5 10 15 20)) ; ==> (10 15 20)
编辑
您评论了一个不同的答案,要求您使用mapcar
,在这种情况下,将其与append
一起使用,以获得所有匹配项的列表,并检查列表中的元素是否大于0:
(defun sublistp (needle haystack)
(flet ((needle-check (x)
(if (equal x needle) '(t) nil)))
(< 0 (length
(apply #'append
(mapcar #'needle-check haystack))))))
(defun子列表(针式草垛)
(针检查(x)
(如果(等于x针)’(t)无)
(<0(长度
(应用#'附加)
(mapcar#“针检干草堆(#)()(#))))
它的工作原理是,对于每个匹配项,您将得到一个包含一个元素的列表,对于每个不匹配项,您将得到一个空列表。添加列表时,如果没有匹配项,则会得到空列表。对于所有其他结果,您有一个匹配项。这不是一个非常有效的实现。下面的过程应该按照您所描述的那样处理
(defun member-nested (el l)"whether el is a member of l, el can be atom or cons,
l can be list of atoms or not"
(cond
((null l) nil)
((equal el (car l)) t)
((consp (car l)) (or (member-nested el (car l))
(member-nested el (cdr l))))
(t (member-nested el (cdr l)))))
以下程序应按照您所述进行处理
(defun member-nested (el l)"whether el is a member of l, el can be atom or cons,
l can be list of atoms or not"
(cond
((null l) nil)
((equal el (car l)) t)
((consp (car l)) (or (member-nested el (car l))
(member-nested el (cdr l))))
(t (member-nested el (cdr l)))))
谢谢你的回答+1我真的在找类似的东西,但找不到。这是一个非常有用的函数,但不幸的是,我出于指令的原因被迫使用<代码> map < /C>:(如果你必须使用<代码> MaPCAR<代码>,请考虑将谓词映射到谓词的另一个列表中,谓词的结果应该是微不足道的,以创建自己的版本<代码> Reals。(如果无法使用内置版本)为了测试是否有任何谓词返回true。好的观点,我将尝试一下。考虑到需要传递到
mapcar
的函数只能有一个参数,有什么办法可以摆脱硬编码的10
吗?你们有没有介绍过lambdas
?如果你们可以使用一个,这将使练习变成trIOVAL。(只是把它传递给外部函数并在lambda中使用它)谢谢你的答案!+ 1我真的在寻找这样的东西,但是找不到。这是一个非常有用的函数,但不幸的是我不得不用<代码> map < /Cord>作为说教的理由:(如果你必须使用<代码> MMACAR< /CODE >,请考虑映射谓词THA。