如何用 nil 创建点对
How to create dotted pair with nil
我有以下形式的队列名称列表:
'("foo" "bar")
我正在尝试通过以下方式将队列存储为关联列表:
'(("foo" . nil) ("bar" . nil))
基本上它是一个关联列表,其中包含当前为空的队列 "foo" 和 "bar"。当 Bob 和 Alice 在 "foo" 队列中时,它应该如下所示。
'(("foo" . ("alice" "bob")) ("bar" . nil))
如何创建这个结构?我试图通过写作来实现这一目标:
(mapcar #'(lambda (x) (cons x ''nil)) '("foo" "bar"))
返回
'(("foo" QUOTE NIL) ("bar" QUOTE NIL))
这可能不是我想要的,因为当我试图将 Bob 推送到 "foo" 队列时,它并没有像我想要的那样工作。
* (setf *tmp* '(("foo" . 'nil) ("bar" . 'nil)))
(("foo" QUOTE NIL) ("bar" QUOTE NIL))
* (push "bob" (caddr (assoc "foo" *tmp* :test #'string=)))
* *tmp*
(("foo" QUOTE ("bob")) ("bar" QUOTE NIL))
如何在点后创建带有空列表的点对?
编辑:
实际上,当我将 assoc 列表存储为 class 插槽时,它看起来不错。
* (describe myClassInstance)
;; ...
QUEUES = (("foo" . 'NIL) ("bar" . 'NIL))
;; ...
然而,在将 Bob 添加到 "foo" 队列之后,所有队列都被更改了。
* (push "bob" (caddr (assoc "foo" (slot-value myClassInstance 'testClass::queues) :test #'string=))))
* (describe myClassInstance)
;; ...
QUEUES = (("foo" . '("bob") ("bar" . '("bob"))
;; ...
这里刚刚发生了什么?看起来所有队列的 cdr
部分都是一个符号,当我在一个地方("foo" 队列)更改它的值时,它在所有地方(所有队列)都被更改。有什么意义吗?
我认为您可能将结构与其印刷表示混淆了。 (cons x nil)
与 '(x . nil)
相同,与 '(x)
相同。它们都将打印为 (x)
.
如果你想打印成 '(x . nil)
你可以为它写一个打印函数,但是表示完全没问题。
cdr为nil的缺点与单元素列表完全相同。这就是列表的定义方式。
换句话说,(cons x nil)
与(list x)
是一样的。你可以想象这样的结果:
+-------+
| x |nil|
+-------+
因此 cdr 是列表的虚线对也只是一个列表。
换句话说,'(("foo" . nil) ("bar" . nil))
与 '(("foo") ("bar"))
完全相同,即使前一种表示法可能更能表达您将其视为列表的意图。
同理,'(("foo" . ("alice" "bob")) ("bar" . nil))
与'(("foo" "alice" "bob") ("bar"))
完全相同。
这意味着您可以完全按照自己的意愿创建数据结构,但您可以使用 e。 G。 list
而不是 (lambda (x) (cons x nil))
(对于单个参数是相同的)。
(defun make-queues (&rest names)
(mapcar #'list names))
您也可以只推送到 assoc
在名称下找到的元素:
(defun add-to-queue (queues queue-name item)
(push item (cdr (assoc queue-name queues :test #'equal))))
(defun get-queue (queues queue-name)
(cdr (assoc queue-name queues :test #'equal)))
您最后遇到的问题是您将文字放入列表并尝试对其进行修改:您将仅包含 nil
的相同 文字列表 放入列表的每个元素。
比较点
CL-USER 48 > (sdraw '(("foo" . ("alice" "bob")) ("bar" . nil)))
[*|*]---------------------------->[*|*]--->NIL
| |
v v
[*|*]--->[*|*]---->[*|*]--->NIL [*|*]--->NIL
| | | |
v v v v
"foo" "alice" "bob" "bar"
无点
CL-USER 49 > (sdraw '(("foo" "alice" "bob") ("bar")))
[*|*]---------------------------->[*|*]--->NIL
| |
v v
[*|*]--->[*|*]---->[*|*]--->NIL [*|*]--->NIL
| | | |
v v v v
"foo" "alice" "bob" "bar"
因此,这两种表示法都描述了相同的 cons 结构。
我有以下形式的队列名称列表:
'("foo" "bar")
我正在尝试通过以下方式将队列存储为关联列表:
'(("foo" . nil) ("bar" . nil))
基本上它是一个关联列表,其中包含当前为空的队列 "foo" 和 "bar"。当 Bob 和 Alice 在 "foo" 队列中时,它应该如下所示。
'(("foo" . ("alice" "bob")) ("bar" . nil))
如何创建这个结构?我试图通过写作来实现这一目标:
(mapcar #'(lambda (x) (cons x ''nil)) '("foo" "bar"))
返回
'(("foo" QUOTE NIL) ("bar" QUOTE NIL))
这可能不是我想要的,因为当我试图将 Bob 推送到 "foo" 队列时,它并没有像我想要的那样工作。
* (setf *tmp* '(("foo" . 'nil) ("bar" . 'nil)))
(("foo" QUOTE NIL) ("bar" QUOTE NIL))
* (push "bob" (caddr (assoc "foo" *tmp* :test #'string=)))
* *tmp*
(("foo" QUOTE ("bob")) ("bar" QUOTE NIL))
如何在点后创建带有空列表的点对?
编辑: 实际上,当我将 assoc 列表存储为 class 插槽时,它看起来不错。
* (describe myClassInstance)
;; ...
QUEUES = (("foo" . 'NIL) ("bar" . 'NIL))
;; ...
然而,在将 Bob 添加到 "foo" 队列之后,所有队列都被更改了。
* (push "bob" (caddr (assoc "foo" (slot-value myClassInstance 'testClass::queues) :test #'string=))))
* (describe myClassInstance)
;; ...
QUEUES = (("foo" . '("bob") ("bar" . '("bob"))
;; ...
这里刚刚发生了什么?看起来所有队列的 cdr
部分都是一个符号,当我在一个地方("foo" 队列)更改它的值时,它在所有地方(所有队列)都被更改。有什么意义吗?
我认为您可能将结构与其印刷表示混淆了。 (cons x nil)
与 '(x . nil)
相同,与 '(x)
相同。它们都将打印为 (x)
.
如果你想打印成 '(x . nil)
你可以为它写一个打印函数,但是表示完全没问题。
cdr为nil的缺点与单元素列表完全相同。这就是列表的定义方式。
换句话说,(cons x nil)
与(list x)
是一样的。你可以想象这样的结果:
+-------+
| x |nil|
+-------+
因此 cdr 是列表的虚线对也只是一个列表。
换句话说,'(("foo" . nil) ("bar" . nil))
与 '(("foo") ("bar"))
完全相同,即使前一种表示法可能更能表达您将其视为列表的意图。
同理,'(("foo" . ("alice" "bob")) ("bar" . nil))
与'(("foo" "alice" "bob") ("bar"))
完全相同。
这意味着您可以完全按照自己的意愿创建数据结构,但您可以使用 e。 G。 list
而不是 (lambda (x) (cons x nil))
(对于单个参数是相同的)。
(defun make-queues (&rest names)
(mapcar #'list names))
您也可以只推送到 assoc
在名称下找到的元素:
(defun add-to-queue (queues queue-name item)
(push item (cdr (assoc queue-name queues :test #'equal))))
(defun get-queue (queues queue-name)
(cdr (assoc queue-name queues :test #'equal)))
您最后遇到的问题是您将文字放入列表并尝试对其进行修改:您将仅包含 nil
的相同 文字列表 放入列表的每个元素。
比较点
CL-USER 48 > (sdraw '(("foo" . ("alice" "bob")) ("bar" . nil)))
[*|*]---------------------------->[*|*]--->NIL
| |
v v
[*|*]--->[*|*]---->[*|*]--->NIL [*|*]--->NIL
| | | |
v v v v
"foo" "alice" "bob" "bar"
无点
CL-USER 49 > (sdraw '(("foo" "alice" "bob") ("bar")))
[*|*]---------------------------->[*|*]--->NIL
| |
v v
[*|*]--->[*|*]---->[*|*]--->NIL [*|*]--->NIL
| | | |
v v v v
"foo" "alice" "bob" "bar"
因此,这两种表示法都描述了相同的 cons 结构。