2015-02-06 23 views
0

我想迭代原子中的值以創建新集合(但不更新​​)。 我有原子的一個定義: let [st (atom {})],現在我想做某事像這樣:基於原子和地圖函數創建新值

(-> (seq (keys @st)) 
    (map (fn [key] [key (get @st key)])))) 

提供的示例被簡化,但即使在這種情況下,我有問題。 我receving下一個錯誤:

java.lang.IllegalArgumentException: Don't know how to create ISeq from: example.test$init$reify__2273$fn__2275 
     at clojure.lang.RT.seqFrom(RT.java:505) 
     at clojure.lang.RT.seq(RT.java:486) 
     at clojure.core$seq.invoke(core.clj:133) 
     at clojure.core$map$fn__4245.invoke(core.clj:2551) 
     at clojure.lang.LazySeq.sval(LazySeq.java:40) 
     at clojure.lang.LazySeq.seq(LazySeq.java:49) 
     at clojure.lang.RT.seq(RT.java:484) 
     at clojure.core$seq.invoke(core.clj:133) 
     at clojure.core$print_sequential.invoke(core_print.clj:46) 
     at clojure.core$fn__5457.invoke(core_print.clj:147) 
     at clojure.lang.MultiFn.invoke(MultiFn.java:231) 
     at clojure.core$pr_on.invoke(core.clj:3392) 
     at clojure.core$pr.invoke(core.clj:3404) 
     at clojure.lang.AFn.applyToHelper(AFn.java:154) 
     at clojure.lang.RestFn.applyTo(RestFn.java:132) 
     at clojure.core$apply.invoke(core.clj:624) 
     at clojure.core$print.doInvoke(core.clj:3449) 
     at clojure.lang.RestFn.applyTo(RestFn.java:137) 
     at clojure.core$apply.invoke(core.clj:624) 
     at clojure.core$print_str.doInvoke(core.clj:4391) 
     ... 
+3

使用 - >>替代 - >(地圖期望序列作爲最後一個參數,而不是第一個) – cgrand 2015-02-06 15:57:54

+0

你說得對!這是非常愚蠢的問題 - 今天編碼太多。 – baju 2015-02-06 16:01:39

+1

我知道這不是真正的代碼,但你不應該刪除一個原子兩次。 – cgrand 2015-02-06 21:11:40

回答

1

的「線程第一」宏(->)插入通過前一表達式返回進入下表達的第二位置的值 - 的函數之後。在你的例子中,這會導致函數調用的參數錯誤(函數應該是第一個,第二個是收集)。這是例外。

在這種情況下,你應該使用「線程最後一個」宏(->>)的值插入到下一個函數調用的最後一個位置:

(let [st (atom {:a 1 :b 2})] 
    (->> (seq (keys @st)) 
     (map (fn [key] [key (get @st key)])))) 
;; returns: ([:b 2] [:a 1]) 

然而,這可以簡化爲以下,因爲地圖可以直接橫移爲序列,其中每個元素的鍵和值的矢量,就像你正在試圖做的:

(let [st (atom {:a 1 :b 2})] 
    (seq @st)) 
;; returns: ([:b 2] [:a 1]) 

如果你正在尋找,你去把這些值,你也可以利用destructuring,fo R實施例一起map呼叫:

(let [st (atom {:a 1 :b 2})] 
    (map (fn [[k v]] [k (+ v 1)]) @st)) 
;; returns: ([:b 3] [:a 2]) 

所以關鍵和值提取您使用該函數聲明。

1

事實上,只用@st是好的 - 原子的是不可改變的。如果您要修改原子,以前檢索的值不會受到影響(假設您使用的是Clojure數據結構)。爲了說明:

(def a (atom {:a 1})) ; => #'user/a 
(def b @a) ; => #'user/b 
(reset! a {:a 2}) ; => {:a 2} 
b ; => {:a 1} 
+0

我沒有添加代碼來添加元素,因爲我認爲它不會改變任何東西 – baju 2015-02-06 16:00:21

+0

@baju刪除第一部分 - 的確如此,在您的示例中將' - >'替換爲' - >>'修正了異常。但是,不需要手動複製數據。 – Jarlax 2015-02-06 16:07:23