从Clojure函数中返回一个映射

Roh*_*ida 1 clojure

我已经学习了几周Clojure了.我知道数据结构和一些功能的基础知识.(我正在阅读Clojure编程书).

我坚持以下.我正在编写一个函数,它将减小所提供地图的键的大小写.

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

这样做我想要的,但我该如何返回地图?是对的def吗?

我知道这很有效

(defn lower-case-map [m]
  (assoc {} :a 1))
Run Code Online (Sandbox Code Playgroud)

doseq上述似乎造成了一个问题.

cfr*_*ick 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}
Run Code Online (Sandbox Code Playgroud)

对于你的用例(修改地图中的所有键)已经是一个很好的核心功能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}
Run Code Online (Sandbox Code Playgroud)