2016-04-06 36 views
1

我不得不在每一個我寫過的Lisp程序中重新實現一個特定的函數。由於這個功能非常有用,它之前必須已經實施。我希望它是衆所周知的。也許它是Common Lisp標準庫的一部分。它叫什麼,它來自哪個庫?滿足謂詞的函數收集子樹的標準名稱?

(defun unknown-function (predicate tree) 
    (loop for item in tree 
     if (funcall predicate item) collect item 
     else if (listp item) append (unknown-function predicate item))) 

它下降通過一棵樹,並創建該樹中所有滿足謂詞的節點的平面列表。

+3

通常,您嘗試執行的任務是通過組合兩個不同的函數解決的,一個是平坦化樹,另一個是過濾來自該列表的元素。在Common Lisp中沒有平坦的原始函數(但是如果你google了,你會發現很多定義,例如見[這個鏈接](http://stackoverflow.com/questions/2680864/how-to-remove-nested) -parentheses-in-lisp)),而對於過濾器函數,可以使用remove-if或remove-if-not([manual](http://www.lispworks.com/documentation/HyperSpec/Body/f_rm_rm.htm #刪除-IF))。 – Renzo

+1

'flatten'和'remove-if-not'不能產生這個函數,因爲謂詞可以從樹中選擇子列表,而flatten會在謂詞有機會看到它們之前擺脫所有的子列表。 –

回答

0

我原來的陳述是錯誤的,因爲其中的子列表在下屬之前由謂詞測試。這是後代:

這沒有標準名稱。這只是一個扁平化列表清單和篩選不滿足謂詞的元素的組合。在Common Lisp中,沒有內置的扁平化,但它可以是自己的扁平化和標準的remove-if-not的組合。

這在普通多一點與subst家族裏面做檢查子樹,除了葉的功能。但是,他們正在替換樹中的單個元素,而不是完全刪除它們。因此,如果和代替,但它們仍然不是完美匹配,但它們與代碼相同。

+1

不完全。在我未知的函數中,謂詞可以從樹中選擇子列表,但是在'remove-if-not'有機會將它們傳遞給謂詞之前,通用的'flatten'函數將刪除所有子列表。 –

+0

哦,這是一個非常好的點!這與** subst **和** subst-if-not **有一些共同之處,我想。這還不是一個完美的比賽,但我已經更新了我的答案。 –

+0

在流行的圖書館裏是否有類似的東西? –