2016-11-13 98 views
0

我有隊列名稱的形式如下列表:如何創建點對與零

'("foo" "bar") 

我試圖存儲隊列爲下列方式assoc命令列表:

'(("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)) 

這可能不是我想要的,因爲當我試圖把鮑勃的「富」排隊不爲工作

我想了。

* (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)) 

如何在點後面創建帶空列表的虛線對?

編輯: 其實當我存儲這樣的關聯列表作爲類插槽它看起來很好。

* (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」隊列)中更改它的值時,它在所有地方(所有隊列)中都發生了變化。它有任何意義嗎?

+0

什麼是'(cons x''nil)'???爲什麼沒有引用兩次? –

+0

''(foo。'nil)'應該是什麼?爲什麼沒有引用? –

+0

@RainerJoswig我現在找不到源代碼,但是有一個地方,我發現這種方式在最後得到了與零的虛線對。這可能是問題所在,但我無法弄清楚如何在點後面的空列表中創建點對。 – dptd

回答

4

cdr爲零的缺點與單元素列表完全相同。這是列表定義的方式。

換句話說,(cons x nil)(list x)相同。你能想象的結果是這樣的:

+-------+ 
| x |nil| 
+-------+ 

的虛線對,其中CDR是一個列表因此還只是一個列表。

換句話說,'(("foo" . nil) ("bar" . nil))'(("foo") ("bar"))完全一樣,即使前面的符號可能更好地表達了您將其視爲alist的意圖。

以同樣的方式,'(("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到您的alist的每個元素。

+0

這真棒。非常感謝你以這種清晰的方式向我澄清這一點。所以基本上每個名單都是一個alist?因爲甚至一個元素列表在點後面包含'hidden''nil'? – dptd

+0

不,一個alist是一個conses列表。列表可以是cons或nil(空列表)。所以非空列表的列表也是一個alist。 – Svante

5

我認爲你可能會將結構與其印刷表示混淆。 (cons x nil)'(x . nil)相同,與'(x)相同。他們將全部打印爲(x)

如果您想打印爲'(x . nil),您可以爲其打印一個打印功能,但表示方式非常好。

+0

這是有道理的,謝謝。 – dptd

2

比較點

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" 

所以,這兩種寫法都描述相同的利弊結構。

+0

謝謝!不知何故,大部分時間我都忘記了真棒'sdraw'。 – dptd