过滤并报告多个谓词

时间:2017-01-23 21:17:50

标签: scala collections filter

这是一种化妆品Scala问题。需要在对象上过滤包含对象的列表。属性。我需要报告对属性的第一次检查是否导致空列表。简化代码:

case class Account (id: Int, balance: Float)

def doFilter(list: List[Account], focusId: Int, thresHold: Float): List[Account] = {
  list.filter(_.id == focusId)
  // ## if at this point if the list is empty, an error log is required.
    .filter(_.balance >= thresHold)
}

var accounts = List(Account(1, 5.0f), Account(2, -1.0f), Account(3, 10f), Account(4, 12f))

println(s"result ${doFilter(accounts, 1, 0f)}")

当然我可以拆分过滤器语句并检查中间结果,但我希望我能用scala方式做更多...我想的就像。

list.filter(_.id == focusId) 
match { case List() => { println "error"; List()}
case _ => _}

但这并不奏效。是否有实现所需行为的功能(或流畅)方式?

3 个答案:

答案 0 :(得分:2)

如果您需要一次,那么记录中间结果可能是最简单的方法。如果你需要在几个地方使用它,你可以使用扩展方法使代码更好:

implicit class ListOps[+A](val list: List[A]) extends AnyVal {
    def logIfEmpty(): List[A] = {
      if (list.isEmpty) {
      println("Error: empty list") 
      // or whatever; you can even pass it as an argument
    }
    list
  }
}

然后你可以像这样使用它:

def doFilter(list: List[Account], focusId: Int, thresHold: Float): List[Account] = list
  .filter(_.id == focusId)
  .logIfEmpty()
  .filter(_.balance >= thresHold)

答案 1 :(得分:2)

以下代码稍加修改this SO answer from Rex Kerr

implicit class KestrelPattern[A](private val repr: A) extends AnyVal {
  def tee[B](f: A => B) = { f(repr); repr } // B is thrown away (Unit)
}

他称之为tap。由于与unix tee命令的相似性,我选择了tee

用法:

scala> List[Int](3,5,7).tee{x => if (x.isEmpty) println("ERROR")}.sum
res42: Int = 15

scala> List[Int]().tee{x => if (x.isEmpty) println("ERROR")}.sum
ERROR
res43: Int = 0

答案 2 :(得分:1)

模式匹配有效,代码错误来自于您在第二种情况下尝试返回_这一事实,您可能需要检查herehere为什么这可能是一个问题:

accounts.filter(_.id == 1) match {
       case List() => { println("error"); List() }
       case x => x.filter(_.balance > 1.0)
}
// res19: List[Account] = List(Account(1,5.0))


accounts.filter(_.id == 5) match {
       case List() => { println("error"); List() }
       case x => x.filter(_.balance > 1.0)
}
// error
// res20: List[Account] = List()