Reputation: 721
Is there any way to put a if inside a match case in scala?
Something like this:
def createSchedules(listTask: List[TaskOrder], physicalResources: List[Physical], humanResources: List[Human], previousTime: Duration): List[TaskSchedule] = listTask match {
case TaskOrder(id, time, physicalRes, order) :: t =>
val taskScheduleHumanResources = setHumanResources(physicalRes, humanResources)
if (physicalRes != null)
new TaskSchedule(
order,
order.getProduct(),
Task(id, time, physicalRes),
physicalRes,
taskScheduleHumanResources,
order.quantity,
previousTime,
previousTime + time) :: createSchedules(t, physicalRes, humanResources, previousTime + time)
case Nil => Nil
}
Doing that I get an error saying:
type mismatch; found : Unit required: List[Objects.TaskSchedule]
What would be the best way to do it?
Upvotes: 2
Views: 1251
Reputation: 149538
The reason the compiler is infering Unit
is that you don't have an else
clause, which means you don't return a value in case physicalRes
is null.
You need to add an else
clause to your code:
case TaskOrder(id, time, physicalRes, order) :: t =>
val taskScheduleHumanResources = setHumanResources(physicalRes, humanResources)
if (physicalRes != null) // stuff
else createSchedules(t, physicalRes, humanResources, previousTime + time)
You can use collect
to only select the desire elements:
val res: List[TaskSchedule] = listTask.collect {
case order if order.physicalRes != null => new TaskSchedule(...)
}
Or you can also fold over the collection and only accumulate when you find non-empty physicalRes
:
val res: List[TaskSchedule] = listTask.foldLeft(List.empty[TaskOrder]) {
case (acc, order) =>
if (order.physicalRes != null) {
new TaskSchedule(...) :: acc
} else acc
}
Upvotes: 5
Reputation: 22477
As others have pointed out, the compiler tries to infer type of the if
expression (it would try and find the first common super-type shared by the if
and else
). Given the lack of an else
, it goes with Unit
, hence the error you were receiving.
If I understand what you are trying to do, collect
ing seems the easiest way to accomplish that:
def createSchedules(listTask: List[TaskOrder], physicalResources: List[Physical], humanResources: List[Human], previousTime: Duration): List[TaskSchedule] =
listTask.collect {
case TaskOrder(id, time, physicalRes, order) if physicalRes != null =>
val taskScheduleHumanResources = setHumanResources(physicalRes, humanResources)
new TaskSchedule(
order,
order.getProduct(),
Task(id, time, physicalRes),
physicalRes,
taskScheduleHumanResources,
order.quantity,
previousTime,
previousTime + time
)
}
Upvotes: 0
Reputation: 41957
If you do
def createSchedules(listTask: List[TaskOrder],
physicalResources: List[Physical],
humanResources: List[Human],
previousTime: Duration): List[TaskSchedule] = listTask match {
case TaskOrder(id, time, physicalRes, order) :: t =>{
val taskScheduleHumanResources = setHumanResources(physicalRes, humanResources);
if(physicalRes != null)
new TaskSchedule(order, order.getProduct(), Task(id, time, physicalRes), physicalRes, taskScheduleHumanResources, order.quantity, previousTime, previousTime + time):: createSchedules(t, physicalRes, humanResources, previousTime + time)
else
Nil
}
case Nil => Nil
}
}
It should work
Upvotes: 1