我正在尝试实施connection scan algorithm。这是下面的工作之一。
班级中的两个val
将被重构,但这不是我的观点。我知道我必须重构foreach
的内容,但我无法理解。 earliest
看起来像一个累加器,所以我想fold
和filter
的组合可能是一种方式......但我对退出条件感到困惑。
case class CSA(timetable: Timetable) {
val inConnection = Array.fill[Int](CSA.MaxStations)(Int.MaxValue)
val earliestArrival = Array.fill[Int](CSA.MaxStations)(Int.MaxValue)
private def loop(arrivalStation: Int): Unit = {
var earliest = Int.MaxValue
timetable.connections.zipWithIndex.foreach { case (connection, index) =>
if (connection.conditionOn(earliestArrival)) {
earliestArrival(connection.arrivalStation) = connection.arrivalTimestamp
inConnection(connection.arrivalStation) = index
if (connection.arrivalStation == arrivalStation) {
earliest = Math.min(earliest, connection.arrivalTimestamp)
}
} else if (connection.arrivalTimestamp > earliest) {
return
}
}
}
/* other stuff */
}
答案 0 :(得分:2)
正如ipoteka已经指出的那样,这可以通过递归函数完成,如:
def loop(arrivalStation: Int): Unit = {
var earliest = Int.MaxValue
@tailrec
def inner(conns: Stream[(Connection, Int)]): Unit = {
conns match {
case Seq() =>
()
case (connection, index) +: tail if connection.arrivalTimestamp > earliest =>
()
case (connection, index) +: tail =>
if (connection.conditionOn(earliestArrival)) {
earliestArrival(connection.arrivalStation) = connection.arrivalTimestamp
inConnection(connection.arrivalStation) = index
if (connection.arrivalStation == arrivalStation) {
earliest = Math.min(earliest, connection.arrivalTimestamp)
}
}
inner(tail)
}
}
inner(timetable.connections.zipWithIndex)
}