【问题标题】:How do I check whether an item is a member of a list in Common Lisp?如何检查一个项目是否是 Common Lisp 中列表的成员?
【发布时间】:2012-07-16 19:37:21
【问题描述】:

我已经实现了这个功能。它应该检查我们给它的输入,如果在列表中找到它,屏幕上将显示“True”。但是,它只适用于数字,如果我给它一个字符,我会收到错误。

(defun element (x lst)
  (dolist (item lst) 
    (if (= item x) (return t))))

我怎样才能修改它以便它也可以查找给它的任何字符? 提前致谢。

【问题讨论】:

    标签: lisp common-lisp


    【解决方案1】:

    有几个比较运算符。一般的有eqeqlequalequalp。在 hyperspec 中查找它们。

    对于特定类型的对象,通常有专门的比较器,例如string=char=

    最后,对于列表操作,还有member 之类的函数,可以让你从手工编写循环中解放出来。它们带有一个可选的test 参数,您可以通过该参数传递比较函数。

    【讨论】:

    • 非常感谢。它工作得很好。但是只有一个问题,“eq”功能和“equalp”功能有什么区别??
    【解决方案2】:

    如您所见,the = function 仅适用于数字。

    如果您尝试将您的函数基于find,您可能会发现它默认使用the eql function 作为其测试提供了您寻求的行为:

    (defun element (needle haystack)
      (not (null (find needle haystack))))
    

    作为find 的替代品,您还应该研究它的兄弟memberposition。在您的情况下,由于您只想区分是否已找到该项目,因此您应该选择工作最少的功能。我的猜测是position 在这里输了,memberfind 是等价的; member 返回从中提取car 的列表,而find 返回car。在这两个函数中,都需要提取car

    【讨论】:

    • 现在只需用“=”符号替换“eq”即可完美运行。非常感谢您的帮助。
    • 我认为您的意思是相反的,将“=”替换为“eq”。确保您了解eqeqlequalequalp 和 kin 之间的区别。
    【解决方案3】:

    很简单,用#'eq 代替#'=,这样第三行就变成了:(if (eq item x) ...

    或者,您可以使用内置的#'intersection 检查列表中是否有任何给定项目,例如:(if (not (eq (intersection lst '(x)) nil)))

    【讨论】:

    • eql 通常是比eq 更好的等式谓词(例如,试试(list (= (/ 1 2) (/ 2 4)) (eq (/ 1 2) (/ 2 4)) (eql (/ 1 2) (/ 2 4))),看看结果是否让您感到惊讶)。
    猜你喜欢
    • 2011-09-02
    • 2014-02-18
    • 1970-01-01
    • 2019-07-26
    • 1970-01-01
    • 2022-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多