0

我有以下代码:

class CSplit(var s1: CanvNode, var s2: CanvNode) extends SplitPane
{         
   topComponent =  s1.merge
   bottomComponent = s2.merge
   def containsV(orig: MapCanvT): Option[MapCanvT]  = 
   {
      def containsIn(cn: CanvNode): Option[MapCanvT] = cn match
      {  
        case Left => None 
        case Right(mc) => if (mc == orig) Some(mc) else None                 
      }
      containsIn(s1) match
      {
        case Some(mc) => Some(mc)
        case None => containsIn(s2)
      }
    }
 }

我想减少 containsV 方法的代码。我的第一个想法是使用 fold 方法来缩短 containsIn 方法。但是 Option 没有,也没有扩展 Class Either。Option[T] 不应该扩展 Either[T, None] 吗?然后至少可以使用 Either 的 fold 方法。

我最后的想法是将 s1 和 s2 视为一个 List 并找到它,但我无法编译:

def containsV(orig: MapCanvT):
  Option[MapCanvT] = ::[CanvNode](s1, s2).find(_ == Right(orig))      
4

3 回答 3

5

Scala 2.10 添加foldOption. 与此同时,您可以map(f).getOrElse(g)改用:

// These produce identical results
o.fold(g)(x => f(x))
o.map(x => f(x)).getOrElse(g)

编辑:所以,例如,以下三个做同样的事情:

val os: List[Option[Int]] = List(Some(5),None)

// Explicit match
os.map{ _ match {
  case Some(x) => x+3
  case None => 0
}}

// map+getOrElse
os.map{ _.map(_+3).getOrElse(0) }

// fold
os.map{ _.fold(0)(_+3) }

在这种fold情况下,您首先给案例的默认值None,然后是处理有值的情况的函数。在每种情况下,您都应该得到List(8,0).

于 2012-08-23T22:08:48.187 回答
2

它可以通过使用 collectFirst 方法的列表来实现

def containsV(orig: MapCanvT): Option[MapCanvT]
  = List(s1, s2).collectFirst {case i: MapCanvT if (i == (orig) => i}    
于 2012-08-26T08:14:02.290 回答
1

让我们从简单的部分开始:

  containsIn(s1) match
  {
    case Some(mc) => Some(mc)
    case None => containsIn(s2)
  }

是相同的

  containsIn(s1) orElse containsIn(s2)

现在我们只需要处理containsIn

  def containsIn(cn: CanvNode): Option[MapCanvT] = cn match
  {  
    case Left => None 
    case Right(mc) => if (mc == orig) Some(mc) else None                 
  }

我们可以使用foldon Either,它摆脱了大部分模式匹配:

 cn.fold(_ => None, Some(_))

但事情就是这样orig。不过,我们可以使用过滤器来处理它:

 cn.fold(_ => None, Some(_)) filter (orig.==)

因此:

def containsV(orig: MapCanvT): Option[MapCanvT]  = {
  def containsIn(cn: CanvNode): Option[MapCanvT] =
    cn.fold(_ => None, Some(_)) filter (orig.==)
  containsIn(s1) orElse containsIn(s2)
}

我认为orElse被忽视了很多。

于 2012-08-23T22:27:08.043 回答