我刚刚学习Clojure,我刚刚写了这个函数:
(defn replace-last [coll value]
(assoc coll (dec (count coll)) value))
我只是担心列表和/或向量可能会非常慢 - 我只是不了解它们还不知道。
谢谢!
答案 0 :(得分:11)
对于向量,这将非常快 - 向量的一个承诺是快速创建略微修改的副本。
对于列表,这根本不起作用 - 它们不是关联的(clojure.lang.Associative
),因此不是assoc
的有效参数。至于其他可能的方法,如果你需要获得一个实际的列表(而不是seq(能)),你运气不好 - 访问/替换列表的最后一个元素基本上是一个线性时间操作。另一方面,如果你可以使用懒惰的seq,它看起来像你的列表,除了最后的元素,你可以实现butlast
的半惰性变体({{1}中的那个) }根本不是懒惰的,并将其用于clojure.core
:
lazy-cat
这会延迟替换最终元素,直到你实际接近它消耗你的seq。
示例互动:
(defn semi-lazy-butlast [s]
(cond (empty? s) s
(empty? (next s)) nil ; or perhaps ()
:else (lazy-seq (cons (first s)
(semi-lazy-butlast (next s))))))
(defn replace-last [s x]
(if (empty? s) ; do nothing if there is no last element to replace
s
(lazy-cat (semi-lazy-butlast s) [x])))
答案 1 :(得分:3)
对于向量,这将与其他任何内容一样快,并且对列表不起作用。