Shortcut to Scala for combining filterNot / match / case

I need to filter a sequence to remove an element that matches a specific case.

This seems too awkward:

val filtered = 
   headers.filterNot{ case Authorization(_) => true; case _ => false }

Is there a more concise / idiomatic way?

+4
source share
5 answers

You can use isInstanceOflike this

headers.filterNot(_.isInstanceOf[Authorization])
+3
source

Your way of doing things seems wonderful. Alternatively, you can take advantage of the fact that casestatement PartialFunctionand use this. Unfortunately, the conclusion of the Scala finicky type makes it more verbose than necessary (otherwise it would be a pretty nice idiom).

// Ideal, but Scala type inference lets us down and this won't compile :(
val filtered0 = headers.filterNot({ case Authorization(_) =>}.isDefinedAt) 
// This will compile, but is crazily verbose
val filtered1 = headers.filterNot(({ case Authorization(_) =>}: PartialFunction[spray.http.HttpHeader, Option[Unit]]).isDefinedAt)

, .

implicit class Matches[T](x: T){
  def matches(pf: PartialFunction[T, Any]) = pf isDefinedAt x
}

val filtered2 = headers filterNot (_ matches {case Authorization(_) =>})
List(Some(1), None) filterNot (_ matches {case None =>}) // List(Some(1))

, case statement PartialFunction s, .

List((5, 2, 'a'), (3, 4, 'b'), (3, 2, 'c')) filterNot (_ matches {case (3, _, x) if x == 'c' =>})
// List((5, 2, a), (3, 4, 'b'))

matches Scala , , matches , OP , .

+1

PartialFunction.cond, :

import PartialFunction.cond

headers.filterNot(cond(_) { case Authorization(_) => true } )
+1
scala> sealed trait Header
defined trait Header

scala> case object Token extends Header
defined object Token

scala> case class Authorization(x: String) extends Header
defined class Authorization

scala> val headers: List[Header] = List(Token, Authorization("foo"))
headers: List[Header] = List(Token, Authorization(foo))

flatMap, , filterNot. flatMap , filterNot - - filter, filterNot:

scala> headers.flatMap { 
     |  case Authorization(_) => Nil
     |  case other => List(other)
     | }
res1: List[Header] = List(Token)
0

As in the original sentence, but matching patterns by type,

headers.filter { 
  case x: Authorization => false
  case _                => true 
}

Another approach involves defining a filter predicate,

def noAuth(h: Header): Boolean = h match {
  case h: Authorization => false
  case _                => true
}

which is then used for filtering,

headers.filter(noAuth)
0
source

Source: https://habr.com/ru/post/1629490/


All Articles