如何替换Clojure中向量中的最后一个元素
作为Clojure的新手,我常常难以表达最简单的东西。例如,用于替换向量中的最后一个元素如何替换Clojure中向量中的最后一个元素,clojure,Clojure,作为Clojure的新手,我常常难以表达最简单的东西。例如,用于替换向量中的最后一个元素 v[-1]=new_value 在python中,我在Clojure中使用了以下变体: (assoc v (dec (count v)) new_value) 至少可以说是相当长且难以表达的,或者 (conj (vec (butlast v)) new_value) 更糟糕的是,它有O(n)运行时间 这让我觉得自己很傻,就像一个穴居人试图用棍棒修理瑞士手表一样 替换向量中最后一个元素的正确方法是什么
v[-1]=new_value
在python中,我在Clojure中使用了以下变体:
(assoc v (dec (count v)) new_value)
至少可以说是相当长且难以表达的,或者
(conj (vec (butlast v)) new_value)
更糟糕的是,它有O(n)
运行时间
这让我觉得自己很傻,就像一个穴居人试图用棍棒修理瑞士手表一样
替换向量中最后一个元素的正确方法是什么
要支持我的
O(n)
-声明butlast
-版本(Clojure 1.8),请执行以下操作:
因此,基本上,10倍的元素数量要慢10倍。如果你坚持“纯粹”,你的第二个或第三个解决方案就会奏效。我更喜欢使用helper函数更简单、更明确:
类似的辅助函数也存在于
- 插入
- 拜访
- 预编
- 附加
(defn set-top [coll x]
(conj (pop coll) x))
比如说,
(set-top [1 2 3] :a)
=> [1 2 :a]
但它也适用于列表的前面:
(set-top '(1 2 3) :a)
=> (:a 2 3)
Clojure堆栈函数——peek
、pop
和conj
——在顺序集合的自然开放端工作
但没有一条正确的道路
各种解决方案如何对空向量作出反应
- 你的Python
抛出异常,你的v[-1]=new_值
和我的(assoc v(dec(count v))new_值)
也抛出异常(defn set-top[coll x](conj(pop coll)x))
- 您的
返回(conj(vec(butlast v))新值)
。[新值]
无效butlast
v
已经是一个向量,那么解决方案#3就不是O(n)(我建议始终使用Clojure向量作为默认选择,除非度量结果证明是错误的)。这是一个界限明确的具体问题和答案,但我认为值得指出的是,许多用Python中的索引表达式表示的算法都有一个惯用的Clojure等价物,它不需要使用索引。@AlanThompson我的测量结果表明它是O(n)
,请看我的编辑。@AlanThompson forbutlast
显示它是的顺序(count coll)
对于序列coll
,如OP所示。与assoc
相比,增益是多少?
(set-top [1 2 3] :a)
=> [1 2 :a]
(set-top '(1 2 3) :a)
=> (:a 2 3)