Clojure中的Assoc-if

时间:2013-05-03 10:34:53

标签: clojure

Clojure库中是否有“assoc-if”功能?即如果值是真实的,则使用给定的键值更新地图。我试图找到这种效果,但缺乏。

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

2 个答案:

答案 0 :(得分:27)

如果目标是避免重复m,则可以使用conj

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

...或Clojure 1.5的新线程宏:

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

如果避免重复mvalue同样重要,那么您必须自己编写或到达clojure.core

之外

答案 1 :(得分:8)

Clojure中没有内置assoc-if函数,但您不是第一个需要它的人。 Check this link的实施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)))