我知道这个问题是旧的,但没有人说,大约差什么 列表和既然你说你真的只是想要的东西,你可以追加 ,并,这听起来像差异表可以帮助你在前面加上。 它们在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