我必须建立一个列表,其成员应该包含或不基于每个成员的不同条件。
假设我必须验证采购订单,并且根据价格,我必须通知许多人:如果价格超过10,则必须通知主管。如果价格超过100,那么主管和经理。如果价格超过1000,那么主管,经理和主管。
我的功能应该以价格作为输入并输出要通知的人员列表。我想出了以下内容:
def whoToNotify(price:Int) = {
addIf(price>1000, "director",
addIf(price>100, "manager",
addIf(price>10, "supervisor", Nil)
)
)
}
def addIf[A](condition:Boolean, elem:A, list:List[A]) = {
if(condition) elem :: list else list
}
在Scala中有更好的方法吗?我用我的addIf
功能重新发明了一些轮子吗?
请注意,价格检查只是一种简化。在现实生活中,检查在许多数据库字段中会更复杂,并且组织层次结构中的某些人不会暗示包括下面的所有人,因此截断列表解决方案将无法工作。
基本上,我想使用不可变列表来实现以下目的:
def whoToNotify(po:PurchaseOrder) = {
val people = scala.collection.mutable.Buffer[String]()
if(directorCondition(po)) people += "director"
if(managerCondition(po)) people += "manager"
if(supervisorCondition(po)) people += "supervisor"
people.toList
}
答案 0 :(得分:4)
您可以使用List#flatten()
从子元素构建列表。它甚至可以让你同时添加两个人(我将在下面的例子中为经理做这些):
def whoToNotify(price:Int) =
List(if (price > 1000) List("director") else Nil,
if (price > 100) List("manager1", "manager2") else Nil,
if (price > 10) List("supervisor") else Nil).flatten
答案 1 :(得分:3)
嗯,这是一个风格问题,但我会这样做,以使所有条件更合适 -
case class Condition(price: Int, designation: String)
val list = List(
Condition(10, "supervisor"),
Condition(100, "manager") ,
Condition(1000, "director")
)
def whoToNotify(price: Int) = {
list.filter(_.price <= price).map(_.designation)
}
您可以根据自己的要求在Condition class
和filter
功能中满足您的所有条件。
答案 2 :(得分:2)
嗯,这是一个风格问题,但我更希望保留一个人员列表来通知规则而不是功能嵌套。在上面的示例中,我没有看到像addIf
这样的内容有多大价值。
我的解决方案。
val notifyAbovePrice = List(
(10, "supervisor"),
(100, "manager"),
(1000, "director"))
def whoToNotify(price: Int): Seq[String] = {
notifyAbovePrice.takeWhile(price > _._1).map(_._2)
}
在现实世界中,如果没有订单或订单不暗示较低级别的通知,那么您可能有notifyAbovePrice
而不是元组的对象而使用filter
代替takeWhile
答案 3 :(得分:1)
如果您有原始成员列表,则可能需要考虑使用filter
方法。如果您还想转换成员对象以便在最后使用不同类型的列表,请查看collect
方法,该方法具有部分功能。