【发布时间】:2012-03-09 13:01:37
【问题描述】:
从 Clojure 映射 {} 中过滤 nil 值的最佳方法是什么?
{ :a :x :b nil :c :z }
;;=> { :a :x, :c :z }
【问题讨论】:
从 Clojure 映射 {} 中过滤 nil 值的最佳方法是什么?
{ :a :x :b nil :c :z }
;;=> { :a :x, :c :z }
【问题讨论】:
我会使用:
(into {} (filter (comp some? val) {:a :x, :b nil, :c :z}))
=> {:a :x, :c :z}
明确地执行some? 检查很重要,因为如果您只执行(into {} (filter val {...})),那么您将错误地删除布尔值为假的值。
【讨论】:
(into {} (remove (comp nil? val) {:a :x :b nil :c :z}))
(filter (complement pred) coll)。带过滤器的版本稍微快一点,带删除的版本稍微短一点:-)
我使用以下代码:
(into {} (filter val {:a 1, :b 2, :c nil}))
;;=> {:a 1, :b 2}
注意:这将删除错误值以及 nils
【讨论】:
可能不是最好的解决方案,但这是使用列表理解的解决方案:
(into {}
(for [[k v] {:a 1 :b nil :c :z} :when (not (nil? v))]
[k v]))
【讨论】:
(into {} (keep (fn [e] (if (val e) e)) {:a :x :b nil :c :z}))
;;=> {:a :x, :c :z}
或者更短一点:
(into {} (keep #(if (val %) %) {:a :x :b nil :c :z}))
事实上,你的过滤器建议更好更短,所以我会使用它:
(into {} (filter val {:a :x :b nil :c :z}))
【讨论】:
这样做最好的方法实际上是(into {} (keep second {:a :x :b nil}))
【讨论】:
into 抛出异常。