Raj Bhatia
Raj Bhatia

Reputation: 1108

How to add an transformed object to set via iterating a list in scala

I'm new to Scala, I'm trying to transform and add an object while iterating a list in Scala, but struggling badly with syntax and probably concept as well.

I want to achieve something like below as we do in JAVA.

public Set<Manager> promoteEmployeesToManager(List<Employee> employees) {
    Set<Manager> managers = new HashSet<Manager>();
    for(employee: employees){
        if(employee.getExprience() > 5) {
              managers.add(promoteEmployee(employee));
        }
    }
    return managers;
}

public Manager promoteEmployee(Employee employee){
    return new Manager(employee);
}

I tried below code but it's not working. In the step of saveNewManagers(newManagers.toArray); the newManagers is still empty.

private def processEmployeePromotion(employees : List[Employee]) {
    val newManagers: Set[Manager] = Set()
    employees.asScala.map(employee => promoteEmployee(newManagers, employee))
    saveNewManagers(newManagers.toArray);
}

Then promoteEmployee method is like:

private def promoteEmployee (newManagers : Set[Manager], employee: Employee){
    if(employee.getExprience() > 5) {
          managers+.(new Manager(employee));
    }
}

Upvotes: 0

Views: 747

Answers (4)

Dima
Dima

Reputation: 40500

 val managers: Set[Manager] = employees
  .iterator
  .filter(_.getExperience > 5) 
  .map(promoteEmployee)
  .toSet

Upvotes: 2

Emiliano Martinez
Emiliano Martinez

Reputation: 4133

When you start to work with Scala you have to get used to work with immutable data structures, foldables, expressions... etc . You can still work with mutable as you used to do with Java if you want but the first is what you should do.

Look at this example using foldLeft from List:

case class Employee(id: String, name: String, experience: Int)
case class Manager(employee: Employee)

object Your_Code extends App {
  def promoteEmployee(employee: Employee) =
    Manager(employee)

  def promoteEmployeesToManager(list: List[Employee]) : Set[Manager] = {
    list.foldLeft(Set[Manager]())((a, b) => if(b.experience > 5) a + promoteEmployee(b) else a)
  }

  val employess = List(Employee("id1", "name1", 6), Employee("id1", "name1", 4))
  println(promoteEmployeesToManager(employess))
}

Upvotes: 0

Levi Ramsey
Levi Ramsey

Reputation: 20551

In Scala, Set is immutable by default, so the + method on Set returns a new set.

private def promoteEmployee(managers: Set[Manager], employee: Employee): Set[Manager] = 
  if (employee.getExperience > 5) {
    managers + new Manager(employee)
  } else {
     managers
  }

private def processEmployeePromotion(employees: List[Employee]): Unit = {
  val newManagers = employees.asScala.foldLeft(Set.empty[Manager]) { (managers, employee) =>
    promoteEmployee(managers, employee)
  }
  saveNewManagers(newManagers.toArray)
}

The major change here is the foldLeft which basically abstracts away the idea of looping and building up the Set.

An alternative strategy would be to have promoteEmployee return an Option[Manager]; you can think of Option as being like a collection of at most one element.

private def promoteEmployee(employee: Employee): Option[Manager] =
  if (employee.getExperience > 5) {
    Option(new Manager(employee))
  } else {
     None
  }

private def promotedEmployees(employees: Iterable[Employee]): Set[Manager] =
  employees.flatMap(promoteEmployee).toSet  // NB: might not work if Manager doesn't obey the equality contract...

private def processEmployeePromotion(employees: List[Employee]): Unit = {
  saveNewManagers(promotedEmployees(employees.asScala).toArray)
}

Upvotes: 0

jwvh
jwvh

Reputation: 51271

So you have a List of employees and you want a List of new managers.

def processEmployeePromotion(employees :List[Employee]) :List[Manager] =
  employees.collect{case emp if emp.getExprience() > 5 => promoteEmployee(emp)}

This will return an empty List if the employees list is empty or if no employees qualify for promotion.

Upvotes: 2

Related Questions