我知道這個問題是舊的,但沒有人說,大約差什麼 列表和既然你說你真的只是想要的東西,你可以追加 ,並,這聽起來像差異表可以幫助你在前面加上。 它們在Clojure中似乎並不流行,但它們非常容易實現,並且比手指樹簡單得多,所以我剛剛製作了一個 微小差異列表庫(甚至測試了它)。這些 連接在O(1)時間(前置或追加)。將差異 列表轉換回列表應該花費你O(n),這是一個很好的折衷,如果 你做了很多連接。如果你沒有做很多 級聯,那麼只需堅持列表,對吧? :)
下面是在這個小小的庫中的函數:
DL:的差異列表實際上是與參數concats自己的 內容,然後返回結果列表的功能。每次你產生一個差異列表 ,你就創建了一個小功能,它的作用就像一個數據結構。
dlempty:由於差異列表只是concats其內容的 說法,一個空的差異列表是一回事身份 功能。
undl:因爲什麼區別名單,則可以只用零調用它轉換 差異列表到正常的列表,所以是不是真的需要這個 功能;這只是爲了方便。
dlcons: conses之外到列表中的前一個項目 - 並非完全 必要的,但consing是一種常見的足夠操作,它只是一個 的一行(像所有的功能,在這裏)。
dlappend:連接兩個差異列表。我認爲它的定義是 最有趣 - 檢查出來! :)
現在,這裏是一個小型庫 - 5個單行函數,給你一個O(1) append/prepend數據結構。不錯,呃?嗯,LAMBDA 微積分的美麗......
(defn dl
"Return a difference list for a list"
[l]
(fn [x] (concat l x)))
; Return an empty difference list
(def dlempty identity)
(defn undl
"Return a list for a difference list (just call the difference list with nil)"
[aDl]
(aDl nil))
(defn dlcons
"Cons an item onto a difference list"
[item aDl]
(fn [x] (cons item (aDl x))))
(defn dlappend
"Append two difference lists"
[dl1 dl2]
(fn [x] (dl1 (dl2 x))))
你可以用這個看到它在行動:
(undl (dlappend (dl '(1 2 3)) (dl '(4 5 6))))
返回:
(1 2 3 4 5 6)
這也返回同樣的事情:
((dl '(1 2 3)) '(4 5 6))
與差異列表玩得開心!
更新
這裏有一些定義可能更難以理解,但我認爲是更好的:
(defn dl [& elements] (fn [x] (concat elements x)))
(defn dl-un [l] (l nil))
(defn dl-concat [& lists] (fn [x] ((apply comp lists) x)))
這讓你說這樣的事情:
(dl-un (dl-concat (dl 1) (dl 2 3) (dl) (dl 4)))
這將返回
(1 2 3 4)
我是不能不指出的是,最後的「醜陋」的例子可以簡化成稍微不那麼醜陋的形式: ''(申請矢量:foo [:bar:baz])'(只是拿出'cons')。 但我同意它有點尷尬,超出'(vector ...)'解決方案,基本上只有'concat'。 如果只有splatting參數的sugary/pretty語法,而不是'apply'(就像'〜@',但不僅僅是宏)...... *嘆息* – chbrown 2017-04-11 06:02:19