2012-02-18 5 views

Odpowiedz

35

użyłbym:

(into {} (filter (comp some? val) {:a :x, :b nil, :c :z})) 

=> {:a :x, :c :z} 

Doing czek some? wyraźnie jest ważne, ponieważ jeśli po prostu zrobić (into {} (filter val {...})) wtedy omyłkowo usunąć wartości, które są boolean false.

+9

. (do {} (remove (comp nil? val) {: a: x: b nil: c: z})) ' – Jonas

+3

Tak, t on usuwa wersję jest równoważny. W rzeczywistości, usunięcie jest faktycznie zaimplementowane w źródle Clojure przy użyciu filtru, jako: '(filter (dopełnij pred) coll)'. Wersja z filtrem jest marginalnie szybsza, wersja z usunięciem jest nieznacznie krótsza do typu :-) – mikera

+0

Co z zagnieżdżonymi zerami? –

0
(into {} (keep (fn [e] (if (val e) e)) {:a :x :b nil :c :z})) 
;;=> {:a :x, :c :z} 

lub nieco krótsza:

(into {} (keep #(if (val %) %) {:a :x :b nil :c :z})) 

W rzeczywistości, sugestia filtr jest znacznie lepszy i krótszy, więc chciałbym po prostu użyć tego:

(into {} (filter val {:a :x :b nil :c :z})) 
+0

przywracany funkcyjne (: x: z) zamiast {: a: x: c: z} – mishadoff

+0

mishadoff: tnx, naprawiono teraz –

5

używam następujący kod:

(into {} (filter val {:a 1, :b 2, :c nil})) 
;;=> {:a 1, :b 2} 

UWAGA: spowoduje to usunięcie fałszywych wartości jak Nils

+5

to filtry są również fałszywe :( –

+0

niż u możesz użyć metody opisanej przez mikerę, ale w większości przypadków mamy logikę, która oznacza zero i vv – mishadoff

3
nie

Prawdopodobnie najlepszym rozwiązaniem, ale tutaj jest jeden, który wykorzystuje listowych:

(into {} 
    (for [[k v] {:a 1 :b nil :c :z} :when (not (nil? v))] 
    [k v])) 
-3

Najpiękniejszych sposobem na to jest rzeczywiście (into {} (keep second {:a :x :b nil}))

+0

(zachowaj drugi {: a: x: b zero}) ==> (: x), "do" rzuca wyjątek. –