13

次のシグネチャを持つ関数を考えてみましょう。

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

マップを関数に渡す最良の方法は何ですか?

(make-widget {:x 100})

また

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

私が現在考えているのは経由vecflattenあり、apply例えば:

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

これを行うためのより良い方法があると強く信じています。ひとつご検討いただけますか?

4

3 に答える 3

11

よりエレガントな方法も考えられませんが、あるべきだと私には思えます(のマップ固有のバリアントのようにapply)。

ただし、使用flattenには非常にエレガントではないということ以外にも問題があります。マップの値がコレクションの場合、 はflattenそれらに対しても再帰的に機能するため、完全に混乱する可能性があります。この代替手段はその問題を回避します。

(apply make-widget (apply concat {:x 100}))
于 2013-10-15T07:37:49.913 に答える
8

既知の(少なくとも私が発明したものではない)関数「mapply」もあります:

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

のように適用できます

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

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

アップデート

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

于 2013-10-17T14:49:10.330 に答える
7

以下を使用できます。

(apply make-widget (mapcat identity {:x 200 :y 0}))
于 2013-10-15T08:36:26.003 に答える