[英]How to filter on a Seq[PartialFunction]
我有一个业务规则列表,并且多个规则可以应用于给定的输入。
type Input = …
type Output = …
type Rule = PartialFunction[Input, Output]
我想编写计算所有有效输出的方法。 我想出了这个实现:
def applyRules(i: Input, rules: Seq[Rule]) : Seq[Output] = {
rules.flatMap(_.lift.apply(i))
}
有没有更好的办法 ?
您的解决方案的一个建议的变体(我想是令人满意的)涉及过滤,然后映射到过滤的结果上。 该方法有效,但涉及同一集合的两次通过,对于较小的集合可能会很好。 但是,我们可以通过以下三种可能的变体达到相同的结果:
collect
方法: rules.collect { case r if r.isDefinedAt(i) => r(i) }
withFilter
而不是filter
: rules.withFilter(_.isDefinedAt(i)).map(_.apply(i))
或 for
理解(与上面的for (r <- rule if r isDefinedAt i) r(i)
相同,但也许更具可读性): for (r <- rule if r isDefinedAt i) r(i)
这些解决方案可能会产生较少的垃圾(每次调用lift
都会创建一个函数对象的新实例- 在这里是代码 ),但是,如果Rule的数量很少,我相信在大多数情况下这不是问题。
您可以使用isDefinedAt
来检查给定的Input
是否可以应用于Rule
:
scala> val pf: PartialFunction[Any, Int] = { case s: String => 42 }
pf: PartialFunction[Any,Int] = <function1>
scala> pf.isDefinedAt(10)
res0: Boolean = false
scala> pf.isDefinedAt("")
res1: Boolean = true
因此,您可以执行以下操作:
val validInputs = rules.filter(_.isDefinedAt(i))
val result = validInputs.map(i)
此外, PartialFunction
包含方法applyOrElse, orElse, ...
,这些方法可能会提高可读性。
如果我误解了您的问题,请纠正我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.