简体   繁体   English

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

[英]Clojure applying a map and keyword arguments destruction

Consider a function with the following signature: 考虑具有以下签名的函数:

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

What is the best way to pass a map to the function, eg: 将地图传递给函数的最佳方法是什么,例如:

(make-widget {:x 100})

or 要么

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

What I have currently thought of is via vec , flatten and apply eg: 我目前想到的是通过vecflattenapply例如:

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

I strongly believe there is a better way to do this. 我坚信有更好的方法可以做到这一点。 Can you please consider one? 你能考虑一下吗?

I can't think of a more elegant way, either, though it seems to me to that there should be one (like a map-specific variant of apply ). 我想不出更优雅的方式,虽然在我看来应该有一个(如地图特定的apply变体)。

Using flatten has problems beyond not being very elegant, though. 但是,使用flatten还有一些问题,而不是非常优雅。 If the values of your map are collections, flatten will work recursively on those, too, so things could get totally mixed up. 如果你的地图的价值是集合,那么flatten也会以递归的方式对这些集合进行处理,所以事情可能会完全混淆。 This alternative avoids that problem: 这个替代方案避免了这个问题:

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

There is also a known (not invented by me at least), function "mapply": 还有一个已知的(至少不是我发明的),功能“mapply”:

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

which can be applied like 哪个可以应用

(mapply your-function {:your "map"})

As to why is this language-specific functionality absent from Clojure core, being implemented more natively and elegantly, no one could ever give me a clear answer. 至于为什么Clojure核心缺少这种特定于语言的功能,更加原生和优雅地实现,没有人能给我一个明确的答案。

UPDATE UPDATE

After I have spent much time programming in Clojure, I personally tend to refrain from creating functions that accept a {} as a vararg. 在Clojure上花了很多时间编程之后,我个人倾向于避免创建接受{}作为vararg的函数。 Although at first this can seem appealing, in reality experience proves that passing an explicit {} is always better for many reasons. 虽然起初这看起来很吸引人,但实际上经验证明,由于许多原因,传递明确的{}总是更好。

您可以使用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM