Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building an immutable List based on conditions

Tags:

scala

I have to build a list whose members should be included or not based on a different condition for each.

Let's say I have to validate a purchase order and, depending on the price, I have to notify a number of people: if the price is more than 10, the supervisor has to be notified. If the price is more than 100 then both the supervisor and the manager. If the price is more than 1000 then the supervisor, the manager, and the director.

My function should take a price as input and output a list of people to notify. I came up with the following:

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
}

Are there better ways to do this in plain Scala? Am I reinventing some wheel here with my addIf function?

Please note that the check on price is just a simplification. In real life, the checks would be more complex, on a number of database fields, and including someone in the organizational hierarchy will not imply including all the people below, so truncate-a-list solutions won't work.

EDIT

Basically, I want to achieve the following, using immutable lists:

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
}
like image 741
Eduardo Avatar asked Jan 20 '13 12:01

Eduardo


People also ask

How do you make an Arraylist immutable?

No, you cannot make the elements of an array immutable. But the unmodifiableList() method of the java. util. Collections class accepts an object of the List interface (object of implementing its class) and returns an unmodifiable form of the given object.

Are elements of a list immutable?

The list is a data type that is mutable. Once a list has been created: Elements can be modified. Individual values can be replaced.

Are asList arrays immutable?

util. Arrays. asList() , the list is immutable.


2 Answers

You can use List#flatten() to build a list from subelements. It would even let you add two people at the same time (I'll do that for the managers in the example below):

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
like image 56
Samuel Tardieu Avatar answered Nov 03 '22 01:11

Samuel Tardieu


Well, its a matter of style, but I would do it this way to make all the conditions more amenable -

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)
}     

You can accommodate all your conditions in Condition class and filter function as per your requirements.

like image 39
Shrey Avatar answered Nov 03 '22 00:11

Shrey