2013-10-15 10 views
11

を適用する:Clojureのは、次のシグネチャを持つ関数を考えてみましょうマップとキーワード引数の破壊

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

例えば、関数にマップを渡すための最良の方法は何ですか:

(make-widget {:x 100}) 

または

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

私が現在考えているのは、vec,flattenおよびです例えば、これはもっと良い方法があると強く信じています。あなたは1つを考慮していただけますか?

答えて

10

私は、マップ固有のバリアントapplyのようなものがあるはずですが、よりエレガントな方法は考えられません。

flattenを使用すると、それほどエレガントではありません。あなたのマップの値がコレクションの場合、flattenもそれらを再帰的に使用するので、事態が完全に混乱する可能性があります。この選択肢は、その問題を回避:

あなたが使用することができます
(apply make-widget (apply concat {:x 100})) 
+0

ノンコムの答えに記載されているmapply関数がこれを行う標準的な方法です。 –

6

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

知られている(少なくとも私によって発明されていない)、機能 "mapply" もあります:

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

適用することができます

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

なぜこの言語特有の機能がClojureのコアに欠けているのか、よりネイティブでエレガントに実装されているので、誰も私に明確な答えを与えることはできませんでした。

UPDATE

私はClojureのに多くの時間プログラミングを過ごした後、私は個人的に可変引数として{}を受け入れる関数を作成控える傾向にあります。最初はこれが魅力的なように思えるかもしれませんが、現実には、明示的な{}を渡すことは、多くの理由により常に優れていることが実証されています。

+1

ユビキタスマappはhttps://github.com/ToBeReplaced/mapplyで私たちのために役立つパッケージになっています。 project.cljの依存関係に[org.tobereplaced/mapply "1.0.0"]を追加するだけです。 –

関連する問題