我有一个像这样的散列图:
{:key1 "aaa bbb ccc" :key2 "ddd eee" :key3 "fff ggg" :do-not-split "abcdefg hijk"}我想分裂一些字符串来得到向量:
; expected result
{:key1 ["aaa" "bbb" "ccc"] :key2 ["ddd" "eee"] :key3 ["fff" "ggg"] :do-not-split "abcdefg hijk"}我现在三次使用update-in,如下所示,但是它看起来很难看。
(-> my-hash (update-in [:key1] #(split % #"\s"))
(update-in [:key2] #(split % #"\s"))
(update-in [:key3] #(split % #"\s")))我希望有像(update-all my-hash [:key1 :key2 :key3] fn)这样的东西
发布于 2013-12-19 10:39:21
您可以使用reduce
user=> (def my-hash {:key1 "aaa bbb ccc" :key2 "ddd eee" :key3 "fff ggg"})
#'user/my-hash
user=> (defn split-it [s] (clojure.string/split s #"\s"))
#'user/split-it
user=> (reduce #(update-in %1 [%2] split-it) my-hash [:key1 :key2 :key3])
{:key3 ["fff" "ggg"], :key2 ["ddd" "eee"], :key1 ["aaa" "bbb" "ccc"]}发布于 2013-12-19 14:52:20
只需根据决定是否拆分的函数映射值即可。
user=> (def x {:key1 "aaa bbb ccc"
:key2 "ddd eee"
:key3 "fff ggg"
:do-not-split "abcdefg hijk"})
#'user/x
user=> (defn split-some [predicate [key value]]
(if (predicate key)
[key (str/split value #" ")]
[key value]))
#'user/split-some
user=> (into {} (map #(split-some #{:key1 :key2 :key3} %) x))
{:do-not-split "abcdefg hijk", :key3 ["fff" "ggg"], :key2 ["ddd" "eee"], :key1 ["aaa" "bbb" "ccc"]}发布于 2013-12-19 11:00:51
这是处理这个问题的另一种方式。
想一想:如果您的字符串在列表中,您将如何处理它?
答案是,您可以使用map获得一个向量列表:
(map #(split % #"\s") list-of-strings)如果您更仔细地思考,您会得出这样的结论:您真正想要的是将映射到,一个函数位于映射的值之上。显然,map在这里不起作用,因为它只对序列起作用。
但是,是否有地图的通用版本?原来是这样的!它叫做fmap,来自函子的概念,你现在可以忽略它。这就是你使用它的方式:
(fmap my-hash #(split % #"\s"))看看现在的意图有多清楚?
惟一的缺点是fmap不是一个核心函数,但它可以通过algo.generic库获得。
当然,如果在这个阶段包含一个新的库感觉太多了,那么您可以从此链接中的库本身始终对源代码--以及它的作者属性进行处理。
(into (empty my-hash) (for [[k v] my-hash] [k (your-function-here v)]))https://stackoverflow.com/questions/20678711
复制相似问题