2011-08-23 3 views
43

スカラ - ラムダパラメータがタプルに一致することはできますか?

そして、私はそれらのうちの1つをフィルタリングしたい、私は

val m = l.filter(item => { 
    val (n, s) = item   // "unpack" the tuple here 
    n != 2 
} 

のような何かをすることができます。この中間のitem変数を持つ代わりにラムダのパラメータを直接?

次のようなものが理想的でしょうが、eclipseは私に言いますwrong number of parameters; expected=1

val m = l.filter((n, s) => n != 2) 

2.9.0.1

答えて

70

を使用して:

val m = l.filter { case (n, s) => n != 2 } 

基本的に匿名の内部のパターンマッチングの構文PartialFunctionです。 Functionオブジェクトと特性にはtupledメソッドもありますが、このパターンマッチング式のラッパーです。

+7

あなたが ''それが使用されることはありませんよう_'でS'交換することができます。 – missingfaktor

+0

これは素晴らしいです、ありがとうございます。 – dvmlls

+1

それよりも短くすることもできます。 –

8

オプションの束があります

for (x <- l; (n,s) = x if (n != 2)) yield x 
l.collect{ case x @ (n,s) if (n != 2) => x } 
l.filter{ case (n,s) => n != 2 } 
l.unzip.zipped.map((n,s) => n != 2).zip // Complains that zip is deprecated 
19

うーんKiptonは良い答えを持っているが。実際にこれを行うことでこれを短くすることができます。

val l = List((1, "blue"), (5, "red"), (2, "green")) 
val m = l.filter(_._1 != 2) 
+0

あなたは優勝者です! –

+4

ショーターはそれを良くしません。これは非常に簡単な例では意味がありますが、より複雑なものについては、Kiptonの例はより読みやすいコードにつながります。 – Chris

+0

私は実際に私の質問に答えないので、私はこれを(5年後)下降させた。私の質問は、どのようにリストをフィルタリングするかではなく、タプルを解凍する方法でした。 – dvmlls

-1

私はこれを熟考し、今日あなたの質問になりました。

論理フローのエントリポイントが増える可能性があることを意味するので、部分的な機能のアプローチ(何かがcaseのもの)があまり好きではありません。少なくとも私には、コードの意図を曖昧にする傾向があります。一方、私は本当にあなたのようなタプルフィールドにまっすぐに行きたいです。

ここに私が今日起草した解決策があります。それはうまくいくようですが、私はまだそれを実際に試していません。

object unTuple { 
    def apply[A, B, X](f: (A, B) => X): (Tuple2[A, B] => X) = { 
    (t: Tuple2[A, B]) => f(t._1, t._2) 
    } 
    def apply[A, B, C, X](f: (A, B, C) => X): (Tuple3[A, B, C] => X) = { 
    (t: Tuple3[A, B, C]) => f(t._1, t._2, t._3) 
    } 
    //... 
} 

val list = List(("a",1), ("b",2)) 
val list2 = List(("a",1,true), ("b",2,false)) 

list foreach unTuple((k: String, v: Int) => 
    println(k, v) 
) 

list2 foreach unTuple((k: String, v: Int, b: Boolean) => 
    println(k, v, b) 
) 

出力:

(a,1) 
(b,2) 
(a,1,true) 
(b,2,false) 

は多分これは有用であることが判明しました。 unTupleオブジェクトは、必然的にいくつかのツールの名前空間に置かれるべきです。

補遺:あなたの場合に適用

val m = l.filter(unTuple((n:Int,color:String) => 
    n != 2 
)) 
+1

Downvoters、なぜdownvoted(StackOverflowで良いマナー)を説明してください。 'unTuple'の代わりに、@ kipton-barrosが参照するビルトインの' Function.tupled'を使うことができます。 – akauppi

4
val m = l.filter((n, s) => n != 2) 

...そのラムダではなく二つのパラメータを持つ

  • Function2[String,Int,Boolean]を定義するため、型の不一致であります
  • Function1[(String,Int),Boolean]であり、1つはTuple2[String,Int]である。

あなたは、このようにそれらの間で変換することができます:

val m = l.filter(((n, s) => n != 2).tupled) 
関連する問題