Построение непреложного Перечня на основе условий

Мне нужно создать список, члены которого должны быть включены или не основаны на другом условии для каждого.

Скажем, я должен подтвердить заказ на поставку, и, в зависимости от цены, я должен уведомить ряд людей: если цена превышает 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
}
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


Ну, это вопрос стиля, но я сделал бы это так, чтобы сделать все условия более подходящими -

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 в соответствии с вашими требованиями.


Ну, это вопрос стиля, но я бы предпочел сохранить список людей для уведомления с помощью правил, а не для функции вложенности. Я не вижу большой ценности, имея что-то вроде 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, если нет порядка или порядок не означает уведомления на более низком уровне.


Если у вас есть исходный список участников, вы, вероятно, захотите рассмотреть метод filter. Если вы также хотите преобразовать объект-член, чтобы в конце иметь другой тип списка, взгляните на метод collect, который принимает частичную функцию.

licensed under cc by-sa 3.0 with attribution.