我需要过滤一个序列以删除与某个案例匹配的元素。
这看起来太笨拙了:
val filtered =
headers.filterNot{ case Authorization(_) => true; case _ => false }
是否有更简洁/惯用的方式?
答案 0 :(得分:3)
您可以使用isInstanceOf
,就像这样
headers.filterNot(_.isInstanceOf[Authorization])
答案 1 :(得分:2)
您可以使用PartialFunction.cond
来省略错误案例:
import PartialFunction.cond
headers.filterNot(cond(_) { case Authorization(_) => true } )
答案 2 :(得分:1)
你做事的方式似乎很好。或者,您可以利用case
语句为PartialFunction
的事实并利用它。不幸的是,Scala的挑剔型推断使得它比它应该更加冗长(否则它将是一个非常好的小成语)。
// Ideal, but Scala's 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
语句为PartialFunction
的事实,这适用于任意模式。
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
这个想法是对Adriaan Moors' idea on the Scala mailing list的一次小修饰,讨论是否将matches
添加为自己的句法特征,其中OP会遇到您描述的确切问题。
答案 3 :(得分:0)
input class="dateinput form-control" data-date-autoclose="true" data-date-format="yyyy-mm-dd" data-date-start-date="0d" data-date-today-highlight="true" data-provide="datepicker" id="id_target_completion_date" name="target_completion_date" type="text">
你可以使用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
:< / p>
filterNot
答案 4 :(得分:0)
与原始提案类似,但在类型上进行模式匹配,
headers.filter {
case x: Authorization => false
case _ => true
}
另一种方法涉及过滤谓词的定义,
def noAuth(h: Header): Boolean = h match {
case h: Authorization => false
case _ => true
}
然后用于过滤,
headers.filter(noAuth)