Clojure应用地图和关键字参数销毁

时间:2013-10-15 07:03:33

标签: map clojure keyword-argument destruction

考虑具有以下签名的函数:

(defn make-widget [& {:keys [x y] :or {x 10 y 20}}]
 ...)

将地图传递给函数的最佳方法是什么,例如:

(make-widget {:x 100})

(make-widget {:y 200 :x 0})

我目前的想法是通过vecflattenapply例如:

(apply make-widget (flatten (vec ({:x 100}))

我坚信有更好的方法可以做到这一点。你能考虑一个吗?

3 个答案:

答案 0 :(得分:11)

我想不出更优雅的方式,虽然在我看来应该有一个(如apply的地图特定变体。)

使用flatten除了不优雅之外还有其他问题。如果您的地图的值是集合,flatten也会以递归的方式处理这些集合,因此事情可能会完全混淆。这个替代方案避免了这个问题:

(apply make-widget (apply concat {:x 100}))

答案 1 :(得分:8)

还有一个已知的(至少不是我发明的),功能“mapply”:

(defn mapply [f & args] (apply f (apply concat (butlast args) (last args))))

可以像

一样应用
(mapply your-function {:your "map"})

至于为什么Clojure核心缺少这种特定于语言的功能,更加原生和优雅地实现,没有人能给我一个明确的答案。

<强>更新

在Clojure上花了很多时间编程之后,我个人倾向于避免创建接受{}作为vararg的函数。虽然起初这看起来很吸引人,但实际上经验证明,由于许多原因,传递明确的{}总是更好。

答案 2 :(得分:7)

您可以使用:

(apply make-widget (mapcat identity {:x 200 :y 0}))