2011-07-16 6 views
6

値を収集するために変更可能なデータ構造を使用せずに、単一の値を複数の「特性」の集合に変換したいと思います。変換する慣用句A => Seq [B]

scala> 2 multimatch { 
    case i if i > 0 => "Positive" 
    case i if i < 0 => "Negative" 
    case i if (i % 2 == 0) => "Even" 
    //yadda yadda 
} 
res0: Seq[java.lang.String] = List(Positive, Even) 
+0

一致するケースは1つだけです。あなたはそれらを入れ子にする必要がありますので、2が肯定的であると認識されることがありますか? – agilesteel

+0

ええ、私はパターンマッチングに似た何かを説明しています。ここで> 1マッチが返されます。 –

答えて

21

class MultiMatcher[A](a: A) { 
    def multiMatch[B](pfs: PartialFunction[A, B]*): Seq[B] = { 
    pfs.map(_.lift(a)).collect{ case Some(v) => v } 
    } 
} 

implicit def toMultiMatcher[A](a:A): MultiMatcher[A] = new MultiMatcher(a) 

2 multiMatch (
    { case i if i > 0 => "Positive" }, 
    { case i if i < 0 => "Negative" }, 
    { case i if i % 2 == 0 => "Even" } 
) 
// returns Seq[java.lang.String] = ArrayBuffer(Positive, Even) 
+0

クール!これをScalaライブラリにする必要があります。 – Landei

+0

'pfs.flatMap(_。lift(a))'はなぜですか? –

+0

暗黙の変換は 'opt-in'になりました。暗黙の変換を定義する前に 'import scala.language.implicitConversions'を追加してください。 –

8

まずあなたがintからオプションへの関数としてあなたの特性を定義し、[文字列]

val pos = (i:Int) => if (i > 0) Some("Positive") else None 
val neg = (i:Int) => if (i < 0) Some("Negative") else None 
val even = (i:Int) => if (i % 2 == 0) Some("Even") else None 

:私は、パターンマッチングを使用しますが、最初の試合後に停止しない、このファンタジーの構造のようなものが欲しいです次に、特性のリストを作成します。

val characteristics = pos::neg::even::Nil 

フラットマップを使用して、特定のオブジェクトに適用される特性のリストを取得します。

これは私が得ることができるどれだけ近いかで、売春斡旋業者のパターン、一部の機能や繰り返しのパラメータを使用して
scala> characteristics.flatMap(f=>f(2)) 
res6: List[java.lang.String] = List(Positive, Even) 
2

まず、次のようにmultimatch関数を定義:

scala> def multimatch[A,B](value : A,ps: (A => Boolean, B)*) = 
    |   for (p <- ps 
    |     if (p._1(value))) yield p._2 
multimatch: [A,B](value: A,ps: ((A) => Boolean, B)*)Seq[B] 

その後ここに行きます:

scala> multimatch(2, 
     |   (((x :Int) => x > 0) -> "POSITIVE"), 
     |   (((x :Int) => x < 0) -> "NEGATIVE"), 
     |   (((x :Int) => x % 2 == 0) -> "EVEN") 
     |  ) 

res4: Seq[java.lang.String] = ArrayBuffer(POSITIVE, EVEN) 

または、あまり混乱しない:

scala> multimatch(2, 
    |   ((x :Int) => x > 0 , "POSITIVE"), 
    |   ((x :Int) => x < 0, "NEGATIVE"), 
    |   ((x :Int) => x % 2 == 0, "EVEN") 
    |  ) 
res5: Seq[java.lang.String] = ArrayBuffer(POSITIVE, EVEN) 
関連する問題