我有一个我想要过滤的持久性地图.像这样的东西:
(filter #(-> % val (= 1)) {:a 1 :b 1 :c 2})
以上是([:a 1] [:b 1])(一个懒惰的地图条目序列).但是我希望得到{:a 1 :b 1}.
如何过滤地图以使其保持地图而无需从一系列地图条目重建地图?
kot*_*rak 49
还有一个:
(let [m {:a 1 :b 2 :c 1}]
  (select-keys m (for [[k v] m :when (= v 1)] k)))
Mic*_*zyk 20
(into {} (filter #(-> % val (= 1)) {:a 1 :b 1 :c 2}))
当然,这确实会从一系列地图条目重建地图,但是无法绕过它.如果您要按值过滤条目,则必须逐个浏览它们,以查看哪些值与谓词匹配,哪些值不匹配.
更新(见下面的评论):
使用新引入的keep函数,你可以在这里看到它的源代码(如果你想要反向移植,应该在Clojure 1.1中运行得很好),如果你不使用它nil作为键,这似乎是一个很好的方法:
(let [m {:a 1 :b 1 :c 2}]
  (apply dissoc m (keep #(-> % val (= 1) (if nil (key %))) m)))
; => {:a 1, :b 1}
此外,如果您确实看到与重建地图相关的减速,则可以在重建步骤中使用瞬态地图:
(persistent! (loop [m (transient {})
                    to-go (seq [[:a 1] [:b 2]])]
               (if to-go
                 (recur (apply assoc! m (first to-go))
                        (next to-go))
                 m)))
; => {:a 1, :b 2}