2014-03-06 24 views
0

clojure中,我想對一個序列的所有元素應用一個函數,並返回一個map,其中的鍵是序列中的元素並且這些值是映射序列的元素。在clojure中,如何映射一個序列並創建散列圖

我寫了下面的函數函數。但我想知道爲什麼這樣的功能不是clojure的一部分。也許它不是慣用的

(defn map-to-object[f lst] 
    (zipmap lst (map f lst))) 


(map-to-object #(+ 2 %) [1 2 3]) => {1 3, 2 4, 3 5} 
+1

沒有錯。你可能還會看到'(到{}(地圖(juxt identity f)coll))'。核心中類似的功能是爲常見用例「記憶」。 –

+0

@ A.Webb您能詳細說明與「memoize」的連接嗎? – viebel

+0

如果函數爲f,並且結果圖爲m,則在(lx)域中'(f x)'和'(m x)'具有相同的值。然而,'(m x)'的值已經被預先計算,換句話說就是memoized。 –

回答

2

你的功能是完全習慣的。

對於一個fn成爲核心的一部分,我認爲它應該對大多數人有用。核心語言的一部分是什麼,什麼不是很有爭議。考慮一下你可以在Java中找到的StringUtils類的數量。

2

我的評論被去太長篇大論,所以......

  1. 沒有錯,你的任何代碼。
  2. 您可能也會看到(into {} (map (juxt identity f) coll))
  3. 這樣做的一個常見原因是緩存某些功能的輸入結果。
  4. 還有其他的用例,例如你已經完成了,例如當特別需要散列圖時。
  5. 當且僅當#3碰巧是你的用例,然後memoize爲你做這個。

如果函數是f,將得到的地圖是m然後(f x)(m x)具有在域的值相同。但是,(m x)的值已經預先計算,換句話說,已被記錄。

事實上,memoize在場景背後確實做了同樣的事情,它只是不能直接訪問地圖。以下是對memoize來源的微小修改以查看此內容。

(defn my-memoize 
    "Exactly the same as memoize but the cache memory atom must 
    be supplied as an argument." 
    [f mem] 
    (fn [& args] 
    (if-let [e (find @mem args)] 
     (val e) 
     (let [ret (apply f args)] 
     (swap! mem assoc args ret) 
     ret)))) 

現在,證明

(defn my-map-to-coll [f coll] 
    (let [m (atom {}) 
     g (my-memoize f m)] 
    (doseq [x coll] (g x)) 
    @m)) 

而且,正如你的榜樣

(my-map-to-coll #(+ 2 %) [1 2 3]) 
;=> {(3) 5, (2) 4, (1) 3} 

但需要注意的是參數(或多個)被封裝在一個序列memoize的處理多種元數函數以及。

+0

感謝您的詳細解答。我很感激。 – viebel