是否有Clojure函数在持久映射中交换两个键值?

时间:2016-03-23 20:47:26

标签: collections clojure clojurescript

是否有Clojure函数在持久映射中交换两个键的值? 我的意思是这样的:

(defn swap-keys [map k1 k2]
  (let [f (get map k1) s (get map k2)]
    (assoc map k1 s k2 f)))

(swap-keys {:a 1 :b 2 :c 3 :d 4} :a :c)
;; => {:a 3, :b 2, :c 1, :d 4}

1 个答案:

答案 0 :(得分:12)

我所知道的最好的是this

(clojure.set/rename-keys {:a 1 :b 2 :c 3 :d 4}
                         {:a :c, :c :a})
;; {:c 1, :b 2, :a 3, :d 4}

如果你愿意,你可以用它做更多的事情而不仅仅是双向交换:

(clojure.set/rename-keys {:a 1 :b 2 :c 3 :d 4}
                         {:a :b,
                          :b :c,
                          :c :d,
                          :d: :a})
;; {:b 1, :c 2, :d 3, :a 4}

编辑:这种方法的好处(可能)超过"天真"解决方案是它执行检查以确保实际存在必要的密钥:

=> (defn swap [m k1 k2] (assoc m k1 (m k2) k2 (m k1)))
=> (swap {:a 1 :b 2 :c 3} :a :d)
;; {:a nil, :b 2, :c 3, :d 1}

=> (clojure.set/rename-keys {:a 1 :b 2 :c 3} {:a :d, :d :a})
;; {:b 2, :c 3, :d 1}