考虑具有以下签名的函数:
(defn make-widget [& {:keys [x y] :or {x 10 y 20}}]
...)
将地图传递给函数的最佳方法是什么,例如:
(make-widget {:x 100})
或
(make-widget {:y 200 :x 0})
我目前的想法是通过vec
,flatten
和apply
例如:
(apply make-widget (flatten (vec ({:x 100}))
我坚信有更好的方法可以做到这一点。你能考虑一个吗?
答案 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}))