在foreach中累加器上的退出条件

时间:2015-08-18 08:36:49

标签: scala functional-programming

我正在尝试实施connection scan algorithm。这是下面的工作之一。

班级中的两个val将被重构,但这不是我的观点。我知道我必须重构foreach的内容,但我无法理解。 earliest看起来像一个累加器,所以我想foldfilter的组合可能是一种方式......但我对退出条件感到困惑。

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 */
}

1 个答案:

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