【问题标题】:Using Clojure update-in with multiple keys使用具有多个键的 Clojure 更新
【发布时间】:2013-03-27 06:27:21
【问题描述】:

我正在尝试将函数应用于映射中与某个键匹配的所有元素。

(def mymap {:a "a" :b "b" :c "c"}) 
(update-in mymap [:a :b] #(str "X-" %))

期待

{:a "X-a", :c "c", :b "X-b"}

但我明白了

ClassCastException java.lang.String 无法转换为 clojure.lang.Associative clojure.lang.RT.assoc (RT.java:702)

有人可以帮我吗?

【问题讨论】:

    标签: map clojure


    【解决方案1】:

    update-in 是更新映射中的单个键(在特定的嵌套级别,[:a :b] 表示更新键:a 的映射值内的键:b。

    你想要的可以使用reduce来完成:

    (reduce #(assoc %1 %2 (str "X-" (%1 %2)))
            mymap
            [:a :b])
    

    【讨论】:

    • (into mymap (for [k [:a :b]] [k (str "X-" (mymap k))]))
    • @amalloy 哪个更惯用?
    【解决方案2】:

    这是一个广义函数:

    (defn update-each
      "Updates each keyword listed in ks on associative structure m using fn."
      [m ks fn]
      (reduce #(update-in %1 [%2] fn) m ks))
    
    (update-each mymap [:a :b] #(str "X-" %))
    

    【讨论】:

      【解决方案3】:

      在下面的解决方案中,haspmap如果先过滤,然后映射到str函数,再和原来的hashmap合并——

      (def m {:a "a" :b "b" :c "c"})
      (def keys #{:a :b})
      
      (->> m
          (filter (fn [[k v]] (k keys)))
          (map (fn [[k v]] [k (str "X-" v)]))
          (into {})
          (merge m)) 
      

      【讨论】:

      • 你能解释一下这是如何解决原始问题而不是简单地发布代码吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-04
      • 1970-01-01
      • 1970-01-01
      • 2020-01-02
      • 2020-12-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多