我有以下课程:
class Task(val Time: Int)
和
class TaskSchedule(val Start: Int, val: End: Int)
我的目标是创建一个TaskSchedule列表,它从任务列表中迭代地总计时间。
因此,例如,如果任务列表的第一个元素的时间为100,则生成的TaskSchedule列表的第一个元素将具有开始0和结束100.如果以下任务的时间为200,则相应的taskSchedule的起点为100(前一个的总和的结果)和300的结尾。
我试图用地图做这个,但我不知道如何获得前一个总和,或者如何将总和传递给下一个迭代。
tasks.map(t => {
new TaskSchedule(
//need previous sum or 0 if first,
)
})
地图可以吗?或者我是否必须改变我对此问题的处理方法?
答案 0 :(得分:2)
简单解决方案
从TaskSchedule
的空列表开始,增量为0.在每一步,使用从TaskSchedule
到delta
+时间创建delta
。将修改后的列表与我们添加了当前时间的新delta
一起返回,以便下一步说明它。
一些附注,类别参数在Scala中不需要大写,你可以在那里使用case class
。
case class Task(time: Int)
case class TaskSchedule(start: Int, end: Int)
def interleave(tasks: List[Task]): List[TaskSchedule] = {
val (schedules, _) = tasks.foldLeft(List.empty[TaskSchedule] -> 0) { case ((list, delta), task) =>
(TaskSchedule(delta, delta + task.time) :: list) -> (delta + task.time)
}
schedules.reverse
}
val result = interleave(List(Task(100), Task(200)))
Console.println(result)
// List(TaskSchedule(0,100), TaskSchedule(100,300))
为避免逆转,您可以改用append。
def interleave(tasks: List[Task]): List[TaskSchedule] = {
val (schedules, _) = tasks.foldLeft(List.empty[TaskSchedule] -> 0) { case ((list, delta), task) =>
(list :+ TaskSchedule(delta, delta + task.time)) -> (delta + task.time)
}
schedules
}
答案 1 :(得分:2)
Seq#scanLeft(...)操作最接近您的需要:
tasks.
scanLeft(new TaskSchedule(0, 0)) {
case (lastSched: TaskSchedule, task: Task) => new TaskSchedule(lastSched.End, lastSched.End + task.Time)
}.
tail
这是一个替代实现,您无需先创建new TaskSchedule(0, 0)
:
tasks.tail.scanLeft(new TaskSchedule(0, tasks.head.Time)) {
case (lastSched: TaskSchedule, task: Task) => new TaskSchedule(lastSched.End, lastSched.End + task.Time)
}
我会让你自己决定哪个更干净(我很难决定自己,虽然第二个实现创建了一个更少的对象)。
如果您制作Task
和TaskSchedule
案例类,可以让事情变得更清晰:
case class Task(time: Int)
case class TaskSchedule(start: Int, end: Int)
tasks: Seq[Task] = ...
tasks.tail.scanLeft(TaskSchedule(0, tasks.head.time)) {
case (TaskSchedule(_, lastEnd), Task(time)) => TaskSchedule(lastEnd, lastEnd + time)
}
顺便提一下,Scala约定是用小写命名变量(即time
而不是Time
,start
而不是Start
,end
代替End
)。