转换A => Seq [B]的惯用方法

Ada*_*ung 6 scala

我想将单个值转换为多个"特征"的集合,而不使用可变数据结构来收集值.我喜欢这样的幻想构造,它使用模式匹配,但在第一次匹配后不会停止:

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)
Run Code Online (Sandbox Code Playgroud)

huy*_*hjl 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)
Run Code Online (Sandbox Code Playgroud)


Kim*_*bel 8

首先,您将特征定义为从Int到Option [String]的函数

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
Run Code Online (Sandbox Code Playgroud)

然后列出特征列表.

val characteristics = pos::neg::even::Nil
Run Code Online (Sandbox Code Playgroud)

然后使用flatmap获取适用于某个对象的特征列表.

scala> characteristics.flatMap(f=>f(2))
res6: List[java.lang.String] = List(Positive, Even)
Run Code Online (Sandbox Code Playgroud)