将模式匹配混合到一系列地图和过滤器中

时间:2014-06-09 23:30:55

标签: scala

假设我想执行以下操作,其中我操作scala列表然后执行匹配以转换为选项。有没有办法在没有添加括号的情况下继续链(对于更复杂的例子,嵌套括号看起来有点令人困惑)?

  def foo: Option[Int] = {
    MyUtils.myListOfFoo
      .flatMap(_.barList)
      .filter(_.isGood)
      .toList match {
        case List(bar) => Some(addr)
        case _         => None
      }
      .map(_.getBaz) // would like to do something like this w/o adding parens
      .map(_.numBlah)
  }

2 个答案:

答案 0 :(得分:1)

您可以使用pimp my library pattern来模拟它:

  object MyUtils {

    implicit class ListOpts[A](val l: List[A]) extends AnyVal {
      def myMatch[B](pf: PartialFunction[List[A], Option[B]]): Option[B] =
        pf.applyOrElse(l, (_: List[A]) => None)
      }

    ...
  }

然后将其导入范围

  import MyUtils._

最后,你的parensless管道是

  def foo: Option[Int] = {
    myListOfFoo // imported
      .flatMap(_.barList)
      .filter(_.isGood)
      .toList // Not needed as filter already returns a List
      .myMatch { // resolved implicitly
        case List(bar) => Some(addr)
        case _         => None // Not needed as it's handled by myMatch
      }
      .map(_.getBaz) // would like to do something like this w/o adding parens. Now you can :-)
      .map(_.numBlah)
  }

答案 1 :(得分:-1)

我的意思是这个(我只是删除了match我错了,你必须使用map

  def foo: Option[Int] = {
    MyUtils.myListOfFoo
      .flatMap(_.barList)
      .filter(_.isGood)
      .toList map {
        case List(bar) => Some(addr)
        case _         => None
      }
      .map(_.getBaz) // would like to do something like this w/o adding parens
      .map(_.numBlah)
  }

我编写了这个nonce来检查它:

scala> List(1, 4, 9, 16, 25, 36, 49)
.map (_ * 2)
.map (_ / 2)
.map { case i if i % 2 == 0 => i / 2
       case i if i % 3 == 0 => i / 3
       case i => i * i }
res0: List[Int] = List(1, 2, 3, 8, 625, 18, 2401)

最后,您正在构建的计算类型最好用于理解。