我正在尝试创建一个具有符号/标记和传递的列表的函数
然后该函数将检查列表是否包含符号/标记。如果是,则返回其对应的密钥对,如果不返回nul
我做了一个defparameter:
(defparameter *pairs*
'((apple green)
(banana yellow)
(grape purple)))
然后我做了一个完成任务的功能:
(defun list-pairs (word list)
(if (eq word list)
(rest(list)))
nil))
这样执行的功能:(list-pairs '(banana) *pairs*)
我一直在努力
我想要返回的是黄色,即密钥对
有人可以帮我解释什么是错的。我是LISP的新手
答案 0 :(得分:4)
(second (assoc 'banana *pairs*))
给出
YELLOW
编辑:有关assoc
的文档以及与之配合使用的关联列表(或简称: alists )的概念,请参阅Joshua Taylor的评论(非常简要说明: alists 是由缺点单元格列表形成的键值数据结构,其中每个缺点单元格的car
是键,cdr
是值。
关于您自己的代码有什么问题:
在if
:(eq word list)
的情况下,您正在测试您的参数word
是否与您的参数list
相同。但实际上你想在word
内寻找list
,因此这不是正确的条件。
此外,即使条件属实,您正在评估的是(rest(list))
。这是通过调用函数list
创建的新空列表的其余部分,而不是您的参数的其余部分list
。
最后,你在if
之后关闭(rest(list))
表达式,并在那里使用第三个右括号。因此,即使其他一切都是正确的,最终的nil
也将是你的函数的返回值。您需要将nil
移动到if
表达式的括号中,使其成为else结果,并将if
表达式的值移动到函数的返回值。
答案 1 :(得分:1)
您正在寻找的是
(defun list-pairs (word list)
(if list
(if (eq (caar list) word)
(cadar list)
(list-pairs word (cdr list))))))
或者,使用let作为小优化:
(defun list-pairs (word list)
(if list
(let ((c (car list)))
(if (eq (car c) word)
(cadr c)
(list-pairs word (cdr list))))))
适用于执行尾调用优化的Common Lisp实现;你应该像
一样使用它(list-pairs 'banana *pairs*)
但在Common Lisp中,循环宏通常是首选:
(defun list-pairs (word list)
(loop for c in list
when (eq (car c) word)
return (cadr c)))
答案 2 :(得分:1)
作为另一种选择:
(defun list-pairs (word list)
(dolist (p list)
(if (eq word (first p))
(return (second p)))))
(defparameter *pairs*
'((apple green)
(banana yellow)
(grape purple)))
(list-pairs 'banana *pairs*)
YELLOW
答案 3 :(得分:0)
你的任务给我留下了一些问题。
1。)你的功能应该有一个符号。但你为什么这样称呼它:(list-pairs '(banana) *pairs*)
?不会(list-pairs 'banana *pairs*)
足够吗?
2。)你只想获得对的第一个元素的匹配吗?即您是否希望符号banana
和yellow
的结果相同?
如果您只想搜索第一个元素,Rörd已经提到assoc
,这将是完美的。
如果您想检查该对中的两个元素,可以尝试remove-if-not
。
(defun list-pairs (word list)
(remove-if-not
#'(lambda (sublist) (member word sublist))
list))