filter and report multiple predicates

后端 未结 3 1237
长发绾君心
长发绾君心 2020-12-21 20:54

This is a kind of cosmetic Scala question. A list with objects needs to be filtered on the objects\' attributes. I need to report if the first check on the attribute results

相关标签:
3条回答
  • 2020-12-21 21:42

    If you need it once, then logging an intermediate result is, probably, the simplest way. If you need this at several places, you can make the code a bit nicer using extension methods:

    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
      }
    }
    

    Then you can use it like this:

    def doFilter(list: List[Account], focusId: Int, thresHold: Float): List[Account] = list
      .filter(_.id == focusId)
      .logIfEmpty()
      .filter(_.balance >= thresHold)
    
    0 讨论(0)
  • 2020-12-21 21:47

    The following code is a slight modification from 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)
    }
    

    He called it tap. I chose tee because of the similarity to the unix tee command.

    Usage:

    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
    
    0 讨论(0)
  • 2020-12-21 21:58

    The pattern matching works, the error of your code comes from the fact that you are trying to return _ in the second case, you may want to check here and here for why this could be a problem:

    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()
    
    0 讨论(0)
提交回复
热议问题