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