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

Is there Clojure function that swaps two keys values in persistent map?

是否有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}

我知道的最好的是 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}

编辑: 这种方法相对于 "naive" 解决方案的一个好处(可能)是它执行检查以确保必要的键确实存在:

=> (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}