2015-07-21 66 views
1

我已經學了幾個星期的Clojure了。我知道數據結構和一些函數的基礎知識。 (我正在閱讀Clojure編程書)。從Clojure功能中返回地圖

我堅持以下幾點。我正在寫一個函數,它將小寫提供的地圖的鍵。

(defn lower-case-map [m] 
    (def lm {}) 
    (doseq [k (keys m)] 
    (assoc lm (str/lower-case k) (m k)))) 

這就是我想要的,但我該如何返回地圖? def正確嗎?

我知道這工作

(defn lower-case-map [m] 
    (assoc {} :a 1)) 

doseq上面似乎是創建一個問題。

+0

你不應該使用'def'上的Clojure函數裏面。 'def'只能用在頂層。改用'let'來定義局部變量。 –

回答

5

在一個函數體,你應該let定義局部變量,但這個代碼看起來很多像你這樣的嘗試將其彎曲成當務之急心態(def tempvar = new Map; foreach k,v in m do tempvar[k.toLower] = v; return tempvar)。還要注意,的doseq明確說明的文檔,它返回nil

功能的方法是在所述輸入直接返回結果的mapreduce。例如一個簡單的方法來map(迭代的元素序列,解構鍵/值元組,發射修改的元組,再將它們成地圖):

user=> (into {} (map (fn [[k v]] [(.toLowerCase k) v]) {"A" 1 "B" 2})) 
{"a" 1, "b" 2} 

爲您的使用情況(修改地圖中的所有鍵)已經是一個很好的核心功能:reduce-kv

user=> (doc reduce-kv) 
------------------------- 
clojure.core/reduce-kv 
([f init coll]) 
    Reduces an associative collection. f should be a function of 3 
    arguments. Returns the result of applying f to init, the first key 
    and the first value in coll, then applying f to that result and the 
    2nd key and value, etc. If coll contains no entries, returns init 
    and f is not called. Note that reduce-kv is supported on vectors, 
    where the keys will be the ordinals. 

user=> (reduce-kv (fn [m k v] (assoc m (.toLowerCase k) v)) {} {"A" 1 "B" 2}) 
{"a" 1, "b" 2} 
+0

當然,多年的命令式編程讓我着迷。努力進入函數式編程。 –