我将从使用speclj框架的测试开始。
(it "turns the string into a hash-map"
(should= {1 "1" 2 "2" 3 "3"}
(format-string "1=1 2=2 3=3")))
然后我的代码:
(:use [clojure.string :only (split)])
(defn format-string [string]
(split string #"\s+"))
现在,format-string
函数返回["1=1" "2=2" "3=3"]
,测试失败。正如您在我的测试中所看到的,我希望它返回一个哈希映射,其中包含由=
符号指示的键值对。
我已经尝试了一些事情,但我已经接近了,但不太明白如何进行这种转变。
修改 的
找出一个解决方案,虽然键是字符串而不是整数。
我的代码:
(defn format-board [route]
(let [[first second third] (split route #"\s+")]
(merge
(apply hash-map (split-at-equals first))
(apply hash-map (split-at-equals second))
(apply hash-map (split-at-equals third))
返回{"1" "1" "2" "2" "3" "3"}
。
答案 0 :(得分:2)
您已在空格处拆分,但之后需要再次在=
分隔符处拆分。您可以使用正则表达式进行解析。拥有配对后,您可以assoc
进入哈希映射。在这里,我使用reduce
来实现转换。
user=> (reduce #(assoc % (read-string (nth %2 1)) (nth %2 2)) {}
#_> (re-seq #"([^=\s]+)=([^=\s]+)" "1=1 2=2 3=3") )
{3 "3", 2 "2", 1 "1"}
注意键顺序不适用于哈希映射
user=> (= {1 "1", 2 "2", 3 "3"} *1)
true
答案 1 :(得分:0)
以下是使用clojure.core.reducers
的潜在并行版本:
(require '[clojure.core.reducers :as r])
(require '[clojure.string :as s])
(def string-of-pairs "1=1 2=2 3=3 4=4")
; reducing fn to convert seq of (key, value) to hash-map
(defn rf ([] {}) ([acc [k v]] (assoc acc k v)))
; for large colls, fold will parallelize execution
(r/fold merge rf (r/map #(s/split % #"=") (s/split string-of-pairs #"\s+")))
为了更好地理解减速器,请注意this video在哪里 Rich解释了减速器背后的动机,并展示了一些用法。