Clojure 将默认值应用于地图
我正在寻找一种将一些默认值应用于地图的方法。我知道以下工作:Clojure 将默认值应用于地图,clojure,Clojure,我正在寻找一种将一些默认值应用于地图的方法。我知道以下工作: (defn apply-defaults [needing-defaults] (merge {:key1 (fn1 10) :key2 (fn2 76)} needing-defaults)) 上面的问题是,即使需要默认值的可能已经有了这些键,也会计算fn1和fn2的值,因此永远不需要它们 我尝试过与合并,但似乎不起作用。我对这一点很陌生-有什么建议吗?如果我正确理解了你的问题,这个
(defn apply-defaults
[needing-defaults]
(merge {:key1 (fn1 10)
:key2 (fn2 76)}
needing-defaults))
上面的问题是,即使需要默认值的可能已经有了这些键,也会计算fn1
和fn2
的值,因此永远不需要它们
我尝试过与合并,但似乎不起作用。我对这一点很陌生-有什么建议吗?如果我正确理解了你的问题,这个怎么样
(defn apply-defaults [nd]
(into {:key1 (sf1 10) :key2 (sf2 76)} nd))
由于可以将nil
合并到地图中,因此可以使用if not
宏:
(merge {} nil {:a 1} nil) ;; {:a 1}
试试这个:
(defn apply-defaults [col]
(merge col
(if-not (contains? col :key1) {:key1 (some-function1 10)})
(if-not (contains? col :key2) {:key2 (some-function2 76)})))
some-function1
和some-function2
仅在col
没有密钥时执行。您可以使用宏生成包含?
检查并短路函数调用
(defmacro merge-with-defaults [default-coll coll]
(let [ks (reduce (fn [a k] (conj a
`(not (contains? ~coll ~k))
`(assoc ~k ~(k default-coll))))
[] (keys default-coll))]
`(cond-> ~coll ~@ks)))
(defn apply-defaults [needing-defaults]
(merge-with-defaults {:key1 (fn1 10)
:key2 (fn2 76)}
needing-defaults))
请记住,将函数调用保留在对与默认值合并的调用中,以防止求值。我通常将默认值与与与函数合并:
(merge-with #(or %1 %2) my-map default-map)
但在你的情况下,应该是这样的:
(reduce (fn [m [k v]]
(if (contains? m k) m (assoc m k (v))))
needing-defaults
defaults)
其中,默认值
是函数的映射:
{ :key1 #(fn1 10)
:key2 #(fn2 76)}
如果
是一种特殊形式,那么它将计算其false
分支
.它似乎不起作用。无论键是否存在于nd
中,都会对函数sf1
和sf2
进行评估(如果您添加了副作用,即println
,您会很容易看到这一点)。我想我误解了您问题的意图。虽然函数变得非常冗长,但它完成了任务。我要等到明天,希望有一个更精益的解决方案存在,有人能想出:)如果没有,答案就留给你:)