Подтвердить что ты не робот

Assoc-if в Clojure

Есть ли в библиотеке Clojure функция "assoc-if"? I. Если значение истинно, обновите карту с заданным значением ключа. Я попытался найти что-то с этой точки зрения, но мне не хватало.

(defn assoc-if
  [m key value]
  (if value (assoc m key value) m))
4b9b3361

Ответ 1

Если цель состоит в том, чтобы избежать повторения m, вы можете использовать conj:

(conj m (when value [key value]))

... или Clojure 1.5 новых макросов для потоковой передачи:

(-> m
  (cond-> value (assoc key value)))

Если действительно важно избегать повторения как m, так и value, вам придется написать свой собственный или выйти за пределы clojure.core

Ответ 2

В Clojure нет встроенной функции assoc-if, но вы не первый, кто ей нужен. Проверьте эту ссылку с помощью assoc-if ALEX MILLER:

(defn ?assoc
  "Same as assoc, but skip the assoc if v is nil"
  [m & kvs]
  (->> kvs
    (partition 2)
    (filter second)
    flatten
    (apply assoc m)))

Но, поскольку flatten является рекурсивным, лучше заменить его чем-то, что нет (спасибо kotarak за подсказку). Другая проблема этой реализации заключается в том, что (apply assoc m) не будет работать в пустом списке. Поэтому лучше всего заменить его на:

(defn ?assoc
  "Same as assoc, but skip the assoc if v is nil"
  [m & kvs]
  (->> kvs
    (partition 2)
    (filter second)
    (map vec)
    (into m)))