斯卡拉:不要在每个周期中返回相同的元素

时间:2017-05-27 19:22:01

标签: 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))

我有这个功能:

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

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

我希望函数返回在其列表中有Worker的第一个元素office,此函数就是这样,然而我想要函数在每个周期中返回不同的结果,我没有成功地尝试这样做。

例如,如果在一个循环中,使用以下参数将函数调用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,我希望以功能方式完成。

你知道我该怎么办?

2 个答案:

答案 0 :(得分:0)

最简单的方法是

<div id="componentdt" ng-app="myApp" ng-controller="MyCtrl" class="container" style="width: 100%">
<div rm-datepicker ng-model="oDate1" rm-config="rmConfig1"></div>
<input type="hidden" id="selectedPartnerId" runat="server" ng-value="oDate1 | date: 'dd-MM-yyyy'" />
</div>

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

答案 1 :(得分:0)

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

这不会从结果列表中删除任何内容,它只是将找到的工作者移动到最后,这样它就不会是下次调用时找到的第一个工作者。

您可能也可以通过这种方法将您的循环变成折叠。