28

Clojure 库中是否有“assoc-if”函数?即,如果一个值是真实的,则使用给定的键值更新映射。我试图找到一些达到这种效果的东西,但缺乏。

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

3 回答 3

37

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

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

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

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

m如果避免重复and确实很重要value,则您必须自己编写或到达外部clojure.core

于 2013-05-04T14:32:01.703 回答
12

Clojure中没有内置assoc-if函数,但您不是第一个需要它的人。使用ALEX MILLER的实现检查此链接assoc-if

(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)))
于 2013-05-03T10:54:16.113 回答
0

只需assoc-some混合库中使用。经过实战测试和广泛使用。

于 2022-01-27T08:04:06.913 回答