Я хотел бы реализовать функцию, которая сопоставляет по последовательности отображений и обновленных значений, когда предикаты соответствуютБолее быстрый/более идиоматический способ достижения «карты-когда»?
Вот первый рабочий проект:
(defn update-if
([m k pred f]
(let [init (get m k)]
(if (and (not-nil? init) (pred init))
(update m k f)
m)))
([m bindings]
(reduce-kv
(fn [agg k v]
(let [[pred f] v]
(update-if agg k pred f)))
m bindings)))
(update-if {:a 1 :b 2} {:a [even? inc] :b [even? dec]}) ;; ==> {:a 1 :b 1}
(update-if {:a 1 :b 2} :b even? dec) ;; ==> {:a 1 :b 1}
(defn map-when
"Walks a collection of associative collections
and applies functions based on predicates
Output :
(map-when {:a [even? inc] :b [nan? zero]} '({:a 1 :b NaN} {:a 2 :b 7} {:a 4 :b NaN}))
=
({:a 1 :b 0} {:a 3 :b 7} {:a 5 :b 0})"
([bindings data]
(reduce
(fn [acc row]
(conj acc (update-if row bindings)))
'() data))
([pred f data]
(map
(fn [x]
(if (and (not-nil? x) (pred x))
(f x)
x))
data)))
Не-ноль? проверка важна (здесь), потому что это просто означает отсутствие данных. Функция занимает около 2 секунд, чтобы выполнить это на 1 миллион случайных карт {:a :b}
(случайный ген включен).
Я чувствую себя странно, что для этого не существует никакой функции в библиотеке, связанной с ядром и ядром. Есть ли подсказки о производительности, чтобы улучшить это? Я попытался преходящим, но он не работает на пустых списках '()
Благодарности