【问题标题】:Scala: don't return same element in each cycleScala:不要在每个循环中返回相同的元素
【发布时间】:2017-10-28 11:32:40
【问题描述】:

我有一个包含以下元素的 Scala 列表:

Worker("W1", "Worker 1", List(Office 1, Office 2))
Worker("W2", "Worker 2", List(Office 1, Office 3, Office 4, Office 5))
Worker("W3", "Worker 3", List(Office 3, Office 5))
Worker("W4", "Worker 4", List(Office 2, Office 4))

我有这个功能:

def setOffice(office: Office.Office, totalWorkers: List[Worker]): Worker = {
      totalWorkers.find(_.offices.contains(office)).getOrElse(null) }
}

它在一个循环内,在循环的每个循环中被调用 3 次(不是函数式方法,但在这种情况下并不重要)。

我希望函数返回列表中包含 office 的第一个元素 Worker,而这个函数就是这样做的,然而我希望函数在每个循环中返回不同的结果,并且我没有成功。

例如,如果在一个循环中,使用此参数调用函数 3 次:

setOffice("Office 1", totalWorkers)
setOffice("Office 2", totalWorkers)
setOffice("Office 3", totalWorkers)

返回:

Worker 1
Worker 1
Worker 2

但我希望它返回

Worker 1
Worker 4
Worker 2

我可以使用变量轻松完成,但我不想使用 var's,我想以函数方式完成。

你知道我该怎么做吗?

【问题讨论】:

标签: scala list functional-programming


【解决方案1】:

最简单的方法是

    def setOffice(office: Office, workers: List[Worker]): (List[Worker], Option[Worker]) =  {
      // Trivial code without optimizations. Just idea.
      val worker = workers.find(_.offices.contains(office))
      (workers.filterNot(worker.contains), worker)
    }

    val (ws1, w1) = setOffice("Office 1", totalWorkers)
    val (ws2, w2) = setOffice("Office 2", ws1)
    val (ws3, w3) = setOffice("Office 3", ws2)

如果您需要理解,遍历办公室列表然后State monad 可能会很方便。

【讨论】:

    【解决方案2】:

    Zernike 返回一个新列表的想法是正确的。但我认为这个解决方案在过滤掉工人方面有点过分热心。如果我理解正确,可能是这样的?

    def setOffice(office: Office, workers: List[Worker]): (Option[Worker], List[Worker]) = {
      val index = workers.indexWhere(_.offices.contains(office))
      if (index == -1) {
        (None, workers)
      } else {
        val (left, x :: right) = offices.splitAt(index)
        (Some(x), left ::: right :+ x)
      }
    }
    

    这不会从结果列表中删除任何内容,它只是将找到的工作人员移动到末尾,这样它就不会成为下一次调用找到的第一个工作人员。

    您也许还可以使用这种方法将循环变成折叠。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-21
      • 2019-04-28
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      相关资源
      最近更新 更多