2012-03-15 8 views
26

Bir haritadan bir tuşa çıkaran bir fonksiyon var?Haritadan birden çok tuş nasıl kaldırılır?</p> <pre><code>(defn remove-key [key map] (into {} (remove (fn [[k v]] (#{key} k)) map))) (remove-key :foo {:foo 1 :bar 2 :baz 3}) </code></pre> <p>Nasıl birden tuşlarını kullanarak bu fonksiyonu uygularım:

(remove-keys [:foo :bar] {:foo 1 :bar 2 :baz 3}) 

Döngü kullanarak bir uygulamam var ... yineleme. Bunu Clojure'da yapmanın daha aptalca bir yolu var mı? Eğer senin remove-key fonksiyonu standart kütüphanesine kapsamındadır

(apply dissoc {:foo 1 :bar 2 :baz 3} [:foo :bar]) 

cevap

44

bir koleksiyon anahtarları varsa,

(dissoc {:foo 1 :bar 2 :baz 3} :foo :bar) 

ya:

(defn remove-keys [keys map] 
    (loop [keys keys 
     map map] 
    (if (empty? keys) 
     map 
     (recur (rest keys) (remove-key (first keys) map))))) 
40

dissoc haritadan bir veya daha fazla anahtar kaldırır işlev dissoc. dissoc, aynı anda birden fazla anahtarı kaldıracak, ancak tuşların doğrudan bir liste yerine argüman listesinde verilmesini istiyor. Yani "düzleştirmek" için apply'u kullanabilirsiniz.

(apply dissoc {:foo 1, :bar 2, :baz 3} [:foo :bar]) 
==> {:baz 3} 
+0

Clojure, bir işlevi bir çağrıda "patlatmaya" yaramaz mı? ala Python'un * listesi? – john2x

+5

@ john2x, 'apply' tam olarak bunu yapar. I.e, '(f foo çubuğu baz uygulanır)' python'da 'f (foo bar * baz)' ile eşdeğerdir. –

11

Diğerlerinin dediği gibi, kendi işlevlerinizi yazmak yerine yerleşik işlevi kullanın.

Ancak bu sadece bir örnek olduğunu ve standart bir dissoc yoktu, o zaman kullanabilirsiniz bunun nasıl bir cevap istiyorsanız: Eğer argümanlar geri eğer

(reduce (fn [m k] (remove-key k m)) {:foo 1 :bar 2 :baz 3} [:foo :bar]) 

Açıkçası çok daha basit yazılabilir anahtar kaldırmak için: https://github.com/boxed/instar:

(reduce remove-key {:foo 1 :bar 2 :baz 3} [:foo :bar]) 
1

Ben bu yüzden kütüphane instar oluşturulan düzeltmek için, Clojure süper can sıkıcı olmaya şey ve diğerleri bu tür buldum.

İlgili konular