2016-03-23 11 views
1

Kalıcı haritada iki anahtarın değerlerini değiştiren Clojure işlevi var mı? Bildiğim en iyilerinden this olduğunuKalıcı haritadaki iki anahtar değerini değiştiren Clojure işlevi var mı?

(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} 
+0

Olası yinelenen: "naif" bir çözüm üzerinde bu yaklaşıma gerekli tuşları gerçekte var emin olmak için bir denetim gerçekleştirir olmasıdır: //stackoverflow.com/questions/5979538/what-is-the-idiomatic-way-to-swap-two-elements-in-a-vector); Bu durumda bir harita ve bir vektör arasında fark yoktur. –

+0

@Elogent Zaten istenen efekti nasıl elde edeceğimi biliyorum, bu işi benim için yapan Clojure standart kütüphanesinde bir işlev aramak istiyorum. Öyleyse, benim sorum nasıl yapılacağı değil, Clojure'ın (eğer varsa) bu işlevi ne yaptığını ve bu nedenle bahsettiğiniz soruların benimkilerden farklı olduğunu. – foki

+0

Her durumda, iki farklı soru aynı cevabı kabul edebilir. :) – galdre

cevap

12

: Böyle bir şey demek

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

İstersen, sadece iki yönlü bir takas daha fazlasını yapmak için kullanabilirsiniz:

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

Düzenleme: bir yararı (muhtemelen) (Http [bir vektör içinde iki öğe takas deyimsel yolu nedir] arasında

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

Bu cevabı kabul ettim ama yine de diğer çözümleri duymak istiyorum. :) – foki