2012-08-02 14 views
10

不要な引数を無視する簡単な方法はありますか?例えば不要な引数を無視するには?

:私はこのコードを返すすぎる3

(#(+ %1 %2) 1 2 3) 

を強制したい (#(+ %1 %2) 1 2)戻り3

。しかしそれは返す

java.lang.IllegalArgumentExceptionを返します:間違った数のargs(3)が に渡されました。

変更方法#(+ %1 %2)

#(+ (nth %& 0) (nth %& 1))よりもさらにエレガントな方法があることを願っています。

(fn [& args] (apply + args)) 

あなただけ(アレックス」はコメントあたりとして)最初の2つの引数を使用する場合:

(fn [& args] (apply + (take 2 args))) 

することができます。これは、任意の数の引数で動作し、かつ読みやすい

答えて

18

は、私が行くと何:

=> ((fn [a b & _] (+ a b)) 1 2 3) 
=> 3 

これは、任意の数の引数を取りますが、ちょうど最初の二つを追加無名関数を作成します。 _シンボルは特別なことをしていません。「このことは気にしませんが、どうにかして縛られる必要があります。あなたはこれをたくさんやってしようとしていると思うなら、あなたはおそらくそれを定義したい:

(defn add-first-two 
    [a b & _] 
    (+ a b)) 

あなたは#()構文に実際にある場合、あなたはそれのための定義で%&どこかを含める必要があります任意の数の議論を取るべきであることを「実現する」。表示するときにインデックスを付ける必要があるわけではありませんが、のどこかにが存在する必要があります。ここでは例です:一方

=> (#(do %& (+ %1 %2)) 1 2 3) 
=> 3 

、このソリューションは、あなたがいずれかを必要としない%&の処理のいくつかの並べ替えを必要とする、と遅いものダウンは少し(私はこれについてはよく分からないことがあり、多分誰かが私にこれに関するフィードバックを与えることができます)。むしろ楽しい解決策は、(comment ...)ブロック内に%&を貼り付けることです。これはnilと評価されます。

=> (#(do (comment %&) (+ %1 %2)) 1 2 3) 
=> 3 

さらに多くのエキゾチックなソリューションは、あなたは、単にそこに何も入力されたなかったかのように読者が実際に、評価から削除することを除いて、多く(comment...)のようである、#_...を使用することです。この方法では、コードを短縮するために(+ ...)の本体の内側に貼り付けることができます。

=> (#(+ %1 %2 #_%&) 1 2 3) 
=> 3 

あなたはそれがうまくいきました。私は実際にこれを試したことはありませんでした、そして、私はそれが動作するのを見てかなり驚いています。明らかに、#_...セクションが削除される前にいくつかの処理があります。奇妙な。

あなたはこれらの奇妙なコメントソリューションのいずれかを好きではない、とdoはあなたが常に(if nil ...)ブロック内に置くことができ、あなたのためにそれをやっていない場合:

=> (#(if nil %& (+ %1 %2)) 1 2 3) 
=> 3 

まあ、すべてのその後((fn ...)を使用して)最初の解決策が最も好きですが、これらのいくつかは確かにです。です。

5

それを直接使用します。

((fn [& args] (apply + (take 2 args))) 1 2) 
; => 3 

またはこのようなシンボルに関数をバインドします

(let [f (fn [& args] (apply + (take 2 args)))] 
    (f 1 2)) 
; => 3 

またはVAR作成:

(def f (fn [& args] (apply + (take 2 args)))) 

または関数:

(defn f [& args] (apply + (take 2 args))) 

を最良の定義があなたのユースケースに依存します。

+2

これはすべての引数の合計です。 OPは最初の2つの合計を求めましたが、エクストラは無視されていましたので、(fn [&args](apply +(2 args)) – Alex

+1

と言わなければなりません。 – Gert

1
user> (#(do %& (+ % %2)) 1 2) 
3 
user> (#(do %& (+ % %2)) 1 2 3) 
3 

これはあまりエレガントではありませんが、私はそれが受け入れられると思います。ここで

4

これはどうですか?

(#(apply + (take 2 %&)) 1 2 3 4 5) 
;; => 3 
関連する問題