1

我将从使用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"}

4

2 回答 2

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
于 2013-01-31T21:03:09.127 回答
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+")))

为了更好地理解 reducer,请观看此视频,其中 Rich 解释了 reducer 背后的动机并演示了一些用法。

于 2013-08-12T10:37:58.503 回答