繁体   English   中英

如何过滤Seq [PartialFunction]

[英]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))
}

有没有更好的办法 ?

您的解决方案的一个建议的变体(我想是令人满意的)涉及过滤,然后映射到过滤的结果上。 该方法有效,但涉及同一集合的两次通过,对于较小的集合可能会很好。 但是,我们可以通过以下三种可能的变体达到相同的结果:

  1. 使用collect方法: rules.collect { case r if r.isDefinedAt(i) => r(i) }
  2. 使用懒惰的withFilter而不是filterrules.withFilter(_.isDefinedAt(i)).map(_.apply(i))
  3. 使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM