[英]Common Lisp: Removing elements with the same cdr
(分配幫助,請放心)(我必須在不使用破壞性函數(setf)的情況下執行此操作)
使用通用Lisp,作為某些代碼的一部分,我需要能夠:
取得列表列表,比較2個元素的cdr;如果相等,則忽略第一個元素;如果不相等,則嘗試將第一個元素與列表中的下一個未經檢查的元素進行比較。
一些例子可以澄清:
(((1 1 1)(2 1 1)(3 1 1))->(((3 1 1)))
((2 2 0)(4 1 1)(1 2 0)(3 0 1)(8 1 1))->(((1 2 0)(3 0 1)(8 1 1))
(defun simplify2 (vari)
;If last term: stop
(if (equal (cdr vari) nil) vari
;If cdr of first and second term are equal...
(if (equal (cdar vari) (cdr (cadr vari)))
;Ignore the first term and continue with the rest of the list
(simplify2 (cdr vari))
;Otherwise (this is the line which isn't working)
(cons (car vari) (simplify2 (cdr vari))))))
目前,只有當所有“喜歡”字詞在列表中並排放置時,代碼才能正常工作。
Le Petit Prince在評論中建議使用刪除重復項可能是您想要的。 remove-duplicates是非破壞性的(請參閱delete-duplicates可能是破壞性的),它被指定為返回一個新列表,其中省略了除元素的最后一個實例之外的所有其他元素(添加了強調):
刪除重復項
remove-duplicates返回序列的修改后的副本,已從該序列中刪除了與按順序出現的另一個元素匹配的任何元素。 …對序列的元素進行成對比較,如果有兩個匹配,則丟棄序列中較早出現的一個 ,除非from-end為true,在這種情況下,序列中較晚的一個被丟棄。
您需要指定一個key參數來指示實際上應該比較的是元素的cdr ,以及一個test參數來指示應該將它們與equal比較。 從而:
(remove-duplicates '((1 1 1) (2 1 1) (3 1 1))
:test 'equal
:key 'cdr)
;=> ((3 1 1))
(remove-duplicates '((2 2 0) (4 1 1) (1 2 0) (3 0 1) (8 1 1))
:test 'equal
:key 'cdr)
;=> ((1 2 0) (3 0 1) (8 1 1))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.