通过调用函数及其键和值来创建嵌套的clojure映射

时间:2017-05-31 20:46:28

标签: dictionary clojure

我遇到了问题。 所以问题是。

  • 我有一张这样的地图{:first {"value1" "value2" "value3"...} :second {"value1" "value2" "value3"...}....}
  • 我有一个功能 使用参数(first&value1)向服务器发出请求并返回 一些信息(它必须用每个键和它们的请求 值(first&value1, first&value2 ...second&value1...)
  • 下一步是生成新的地图,如:

    {:first 
      {:value1 
        {subvalue1, subvalue2 ..} 
       :value2 
        {subvalue2-1,subvalue2-2}}    
     :second
      {:value3 
        {:subvalue3-1,:subvalue3-2}..}..}
    

子值是对每个键及其值的每个项发出请求的结果。 我想再次重复操作(当我向服务器发出请求时有3个参数)来实现4次嵌套映射:{first {second {third {fourth}}}}。 也许有人给我提供了有用的建议。

1 个答案:

答案 0 :(得分:2)

这个功能有点啰嗦,但你需要它做什么:

(defn rec-update
  [m f]
  (let [g (fn g [m args]
            (into {}
                  (for [[k v] m]
                    (if (instance? java.util.Map v)
                      [k (g v (conj args (name k)))]
                      [k (into {} (map #(let [args (into args [(name k) (name %)])]
                                          [(keyword %) (f args)])
                                       v))]))))]
    (g m [])))

f参数应该是一个收集参数集合的函数,并返回结果向量。这是一个选择随机响应随机数的示例:

(defn make-request
  [params]
  (vec (repeatedly (+ 1 (rand-int 3)) #(rand-nth ["r1" "r2" "r3"]))))

虽然以下示例未演示,但此函数的params确实是到此为止的嵌套值。

使用:

(def m {:first ["val1" "val2" "val3"], :second ["val4" "val5"]})

(rec-update m make-request)
=>
{:first {:val1 ["r2" "r2" "r3"], :val2 ["r2" "r2"], :val3 ["r1" "r3"]},
 :second {:val4 ["r3" "r3"], :val5 ["r2" "r1"]}}

在结果上再次运行:

(rec-update *1 make-request)
=>
{:first {:val1 {:r2 ["r1" "r3" "r2"], :r3 ["r3" "r2"]},
         :val2 {:r2 ["r1" "r1"]},
         :val3 {:r1 ["r2"], :r3 ["r1" "r2" "r3"]}},
 :second {:val4 {:r3 ["r3" "r2"]}, :val5 {:r2 ["r1"], :r1 ["r2" "r3"]}}}

如您所见,从请求返回的任何重复值只会在结果映射中表示一次。