0x8*_*x89 54 vector append clojure prepend
在列表前面很容易:
user=> (conj '(:bar :baz) :foo)
(:foo :bar :baz)
Run Code Online (Sandbox Code Playgroud)
附加到矢量很简单:
user=> (conj [:bar :baz] :foo)
[:bar :baz :foo]
Run Code Online (Sandbox Code Playgroud)
在获取向量时,我如何(惯用)前置到向量?这不起作用,因为它返回seq,而不是向量:
user=> (cons :foo [:bar :baz])
(:foo :bar :baz)
Run Code Online (Sandbox Code Playgroud)
这很难看(IMVHO):
user=> (apply vector (cons :foo [:bar :baz]))
[:foo :bar :baz]
Run Code Online (Sandbox Code Playgroud)
注意:我基本上只想要一个可以附加和前置的数据结构.附加到大型列表应该有很大的性能损失,所以我想到了矢量..
kot*_*rak 71
矢量不是为前置而设计的.你只有O(n)前置:
user=> (into [:foo] [:bar :baz])
[:foo :bar :baz]
Run Code Online (Sandbox Code Playgroud)
你想要的很可能是手指树.
Bil*_*ick 17
我知道这个问题已经过时了,但是没有人对差异列表说过什么,因为你说你真的只想要一些你可以追加和添加的东西,听起来差异列表可能对你有帮助.它们在Clojure中似乎并不受欢迎,但是它们非常容易实现,并且比手指树复杂得多,所以我刚才创建了一个微小的差异列表库(甚至测试过它).这些在O(1)时间(前置或附加)中连接.将差异列表转换回列表应该花费你O(n),如果你做了大量的连接,这是一个很好的权衡.如果你没有进行大量连接,那么只需坚持列表,对吗?:)
以下是这个小型库中的函数:
dl:差异列表实际上是一个函数,它使用参数连接自己的内容并返回结果列表.每次生成差异列表时,您都会创建一个像数据结构一样的小函数.
dlempty:由于差异列表只是将其内容连接到参数,因此空差异列表与身份函数相同.
undl:由于列表有什么不同,你可以通过用nil调用它来将差异列表转换为普通列表,所以这个函数并不是真正需要的.这只是为了方便.
dlcons:将一个项目集中到列表的前面 - 并非完全必要,但是consing是一个足够普通的操作,它只是一个单行程序(就像所有函数一样).
dlappend:收集两个不同的名单.我认为它的定义是最有趣的 - 看看吧!:)
现在,这是一个很小的库 - 5个单行函数,它们为您提供O(1)追加/前置数据结构.不错,嗯?啊,Lambda Calculus的美丽......
(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))))
Run Code Online (Sandbox Code Playgroud)
你可以看到它的实际效果:
(undl (dlappend (dl '(1 2 3)) (dl '(4 5 6))))
Run Code Online (Sandbox Code Playgroud)
返回:
(1 2 3 4 5 6)
Run Code Online (Sandbox Code Playgroud)
这也返回相同的东西:
((dl '(1 2 3)) '(4 5 6))
Run Code Online (Sandbox Code Playgroud)
与差异列表玩得开心!
更新
以下是一些可能更难理解的定义,但我认为更好:
(defn dl [& elements] (fn [x] (concat elements x)))
(defn dl-un [l] (l nil))
(defn dl-concat [& lists] (fn [x] ((apply comp lists) x)))
Run Code Online (Sandbox Code Playgroud)
这让你说出这样的话:
(dl-un (dl-concat (dl 1) (dl 2 3) (dl) (dl 4)))
Run Code Online (Sandbox Code Playgroud)
哪会回来
(1 2 3 4)
Run Code Online (Sandbox Code Playgroud)
如果您不害怕准引用,这个解决方案实际上非常优雅(对于“优雅”的某些定义):
> `[~:foo ~@[:bar :baz]]
[:foo :bar :baz]
Run Code Online (Sandbox Code Playgroud)
实际上,我有时会在实际代码中使用它,因为声明性语法使其非常具有可读性(恕我直言)。
归档时间: |
|
查看次数: |
24665 次 |
最近记录: |