[英]How to determine if a list is an alist
有沒有一種簡單的方法來確定列表是否實際上是列表?
我的第一次嘗試:
(defun alistp (list)
(and (listp list)
(every (lambda (c)
(and (consp c)
(or (atom (cdr c))
(null (cddr c))))))
list)))
為(alistp '((1 . 2) (2 . 3)))
返回T
但是對於(alistp '((1 . (4 5 6))))
為NIL
有解決方案嗎?
好,讓我們看一下關聯列表的定義 :
關聯列表 代表鍵與值的關聯的cons列表,其中每個cons的car是鍵,而cdr是與該鍵關聯的值。
鑒於此,這可能是alistp
的可能實現:
(defun alistp (alist)
(and (listp alist) ; a list
(every #'consp alist))) ; of conses
現在,從您的代碼示例中,我可以告訴您您可能已經可以自己實現此功能,但是您似乎對alist的定義有所不同。 我假設您看到的名單示例大致都像這樣: ((a . x) (b . y))
a。x)(b。y ((a . x) (b . y))
,也許((a . x) (b . (yz)))
a。x ((a . x) (b . (yz)))
但是一個虛線列表列表作為最后一個元素只是一個列表,從示例輸入中可以很明顯地看出,您希望允許列表作為值。 (為什么不呢?)
我想,您必須了解的是您的示例輸入((1 . (4 5 6)))
與 ((1 4 5 6))
完全相同 ,這就是我通常如何看待列表為列表的列表的方式代碼中使用的值–至少,這是我通常編寫它們的方式。
現在,您似乎也想排除nil
值,盡管它們也是列表-只是空的()
。 因此,您實際上要想到的定義是這樣的:
關聯列表 代表鍵與非零值的關聯的con單元格列表,其中每個cons的car是鍵,而cdr是與該鍵關聯的值。
如果這確實是您想要的,請遵循新的定義:
(defun alistp (alist)
(flet ((true-cdr-p (element)
(and (consp element) ; cons cell
(cdr element)))) ; with non-nil cdr (i.e. value)
(and (listp alist) ; a list
(every #'true-cdr-p alist)))) ; of cons cells with non-nil cdr
或類似的東西。 我建議還是使用上面的簡單版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.