如何在Clojure中替换向量中的最后一个元素

ead*_*ead 8 clojure

作为Clojure的新手,我经常难以表达最简单的事情.例如,用于替换向量中的最后一个元素

v[-1]=new_value
Run Code Online (Sandbox Code Playgroud)

在python中,我最终得到了Clojure中的以下变体:

(assoc v (dec (count v)) new_value)
Run Code Online (Sandbox Code Playgroud)

至少可以说,这是非常漫长和无意义的,或者

(conj (vec (butlast v)) new_value) 
Run Code Online (Sandbox Code Playgroud)

更糟糕的是,因为它有O(n)运行时间.

这让我觉得很傻,就像一个试图用俱乐部修理瑞士手表的穴居人.

用Clojure方法替换向量中的最后一个元素是什么?


为了支持我的O(n)-claim for butlast-version(Clojure 1.8):

(def v (vec (range 1e6)))
#'user/v
user=> (time (first (conj (vec (butlast v)) 55)))
"Elapsed time: 232.686159 msecs"
0
(def v (vec (range 1e7)))
#'user/v
user=> (time (first (conj (vec (butlast v)) 55)))
"Elapsed time: 2423.828127 msecs"
0
Run Code Online (Sandbox Code Playgroud)

所以基本上10次元素的数量要慢10倍.

Thu*_*ail 11

我用了

(defn set-top [coll x]
  (conj (pop coll) x))
Run Code Online (Sandbox Code Playgroud)

例如,

(set-top [1 2 3] :a)
=> [1 2 :a]
Run Code Online (Sandbox Code Playgroud)

但它也适用于列表的前面:

(set-top '(1 2 3) :a)
=> (:a 2 3)
Run Code Online (Sandbox Code Playgroud)

Clojure堆栈函数 - peek,popconj- 在顺序集合的自然开放端工作.

但没有一个正确的方法.


各种解决方案如何对空载体做出反应?

  • 你的Python v[-1]=new_value会引发异常,就像你(assoc v (dec (count v)) new_value)和我的一样(defn set-top [coll x] (conj (pop coll) x)).
  • 你的(conj (vec (butlast v)) new_value)回报[new_value].在butlast没有任何效果.