2015-06-16 52 views
2

我有一個看起來像一個向量:的Clojure - 適用於所有,但第n個元素

[ "1" "2" "3" "4" ] 

我希望寫一個函數返回向量:沒有什麼改變

[ 1 "2" 3 4 ] 
; Note that the second element is still a string 

注,一個全新的矢量被返回。在clojure中做到這一點最簡單的方法是什麼?

回答

5

map-indexed是一個不錯的選擇。調用你傳遞的函數,其中一個項目的值和你找到的索引(首先是索引)是一樣的。該功能可以選擇產生新值或返回現有值。

user> (map-indexed (fn [i v] 
        (if-not (= 1 i) 
         (Integer/parseInt v) 
         v)) 
        [ "1" "2" "3" "4"]) 
(1 "2" 3 4) 

if返回v它在生成的地圖完全相同的值,從而保持在您選擇保留部分結構共享的好處。如果你想把輸出保存爲一個向量,那麼你可以使用mapv並且傳遞你自己的索引序列。

user> (mapv (fn [i v] 
       (if-not (= 1 i) 
       (Integer/parseInt v) 
       v)) 
      (range) 
      [ "1" "2" "3" "4"]) 
[1 "2" 3 4] 

有很多方法來寫這個

1

這裏是我會怎麼做。請注意,該指數是從零開始:

(defn map-not-nth 
    "Transform all elements of coll except the one corresponding to idx (zero-based)." 
    [func coll idx] 
    {:pre [ (<= 0 idx (count coll)) ] 
    :post [ (= (count %) (count coll)) 
      (= (nth coll idx) (nth % idx)) ] } 
    (let [coll-tx (map func coll) ; transform all data 
     result (flatten [ (take idx coll-tx)  ; [0..idx-1] 
          (nth coll idx)   ; idx 
          (drop (inc idx) coll-tx) ; [idx+1..N-1] 
          ]) ] 
    result)) 

(def xx [ 0 1 2 3 4 ]) 

(prn (map-not-nth str xx 0)) 
(prn (map-not-nth str xx 1)) 
(prn (map-not-nth str xx 2)) 
(prn (map-not-nth str xx 3)) 
(prn (map-not-nth str xx 4)) 

結果是:

user=> (prn (map-not-nth str xx 0)) 
(0 "1" "2" "3" "4") 
user=> (prn (map-not-nth str xx 1)) 
("0" 1 "2" "3" "4") 
user=> (prn (map-not-nth str xx 2)) 
("0" "1" 2 "3" "4") 
user=> (prn (map-not-nth str xx 3)) 
("0" "1" "2" 3 "4") 
user=> (prn (map-not-nth str xx 4)) 
("0" "1" "2" "3" 4) 
相關問題