2017-09-21 58 views
7

作爲Clojure的新手,我經常難以表達最簡單的東西。例如,在一個向量替換最後一個元素,這將是如何替換Clojure中的最後一個元素

v[-1]=new_value 
在python

,我結束了在Clojure的下列變量

(assoc v (dec (count v)) new_value) 

這是相當長,無表情的說最少的還是

(conj (vec (butlast v)) new_value) 

哪個更糟,因爲它有O(n)運行時間。

這讓我感到無聊,就像一個試圖用俱樂部修理瑞士手錶的穴居人。

什麼是正確的Clojure方法來替換向量中的最後一個元素?


爲了支持我O(n) -claim爲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 

所以基本上10時元素的數量是慢10倍。

+1

您的第一個辦法就是如何完成。顯然,你可以寫一個「替換 - 最後」的功能來清理它。我認爲Python過於簡潔的表達方式很不幸地破壞了你的期望。我不認爲後端索引經常需要在Clojure中對自己的語法提出警告。 +1,因爲我想證明是錯誤的。 – Carcigenicate

+0

注意:如果'v'已經是一個向量(我推薦總是在Clojure列表上使用Clojure向量作爲默認選項,除非測量結果證明是否爲其他),否則解決方案#3不是O(n)。 –

+1

這是一個定義明確的具體問題和答案,但我認爲值得指出的是,許多用Python中的索引表達式表達的算法都具有不需要使用索引的習慣Clojure等價物。 – glts

回答

9

我會使用

(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的堆棧功能 - peekpopconj - 在順序收集的自然開放式結尾工作。

但沒有一個正確的方法。


各種解決方案如何對空載體做出反應?

  • 你的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不起作用。
1

如果你堅持「純」,你的第二或第三解決方案將工作。我更喜歡使用輔助功能from the Tupelo library要簡單&更加明確:爲

  • 嵌入在
  • 落於
  • 前插
  • 追加
  • 存在

    (s/defn replace-at :- ts/List 
        "Replaces an element in a collection at the specified index." 
        [coll  :- ts/List 
        index :- s/Int 
        elem  :- s/Any] 
        ...) 
    
    (is (= [9 1 2] (replace-at (range 3) 0 9))) 
    (is (= [0 9 2] (replace-at (range 3) 1 9))) 
    (is (= [0 1 9] (replace-at (range 3) 2 9))) 
    As with drop-at, replace-at will throw an exception for invalid values of index. 
    

    類似的輔助函數

請注意,上述所有工作同樣適用於Clojure列表(渴望或懶惰)或Clojure向量。 The conj solution will fail除非你小心總是強制輸入到矢量中,如你的例子。

+3

和'assoc'相比有什麼收穫? – ead

相關問題