Scala:don';t在每个循环中返回相同的元素

Scala:don';t在每个循环中返回相同的元素,scala,list,functional-programming,Scala,List,Functional Programming,我有一个包含以下元素的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)) 我有这个功

我有一个包含以下元素的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的
,我想用一种函数的方式来实现


你知道我该怎么做吗?

最简单的方法是

    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)

如果您需要理解,那么遍历办公室列表可能会很方便

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)
  }
}
这不会从结果列表中删除任何内容,它只是将找到的worker移到末尾,这样它就不会是下一次调用找到的第一个worker


您也可以使用这种方法将循环转换为折叠。

听起来您每次调用此函数时都需要更改工作人员(通过从其办公室列表中删除已找到的办公室),这与函数式语言的引用透明组件相违背:请参阅