2017-05-27 14 views
0

各サイクルで同じ要素を返しません。スカラ:私は、次の要素を持つ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を返すようにしたいですそう。

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

それが返されます:1サイクルで機能は、このパラメータで3回呼び出された場合例えば

Worker 1 
Worker 1 
Worker 2 

しかし、私はそれを返すようにしたい

Worker 1 
Worker 4 
Worker 2 

私は変数を使って簡単に行うことができますが、私はvar'sを使いたくないので、私はそれをしたい機能的な方法。

どうすればいいですか?

+0

この関数を呼び出すたびに(Officeのリストから既に見つかっているオフィスを削除して)作業者を変更する必要があるように思えますが、これは関数言語の参照透過コンポーネントとは異なります。https:// stackoverflow .com/questions/4847818/referential-transparency – Tanjin

答えて

0

最も簡単な方法は、あなたが理解するために必要な場合は、その後、事務所リストのトラバースState monadは便利かもしれない

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) 

です。

0

ゼルニケは新しいリストを返すことで正しいアイデアを持っています。しかし、私はその解決策が労働者を除外するのに少し過激だと思う。もし私が正しく理解していれば、おそらくこのようなものでしょうか?

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

これは、次の呼び出しで最初に見つかったことがないように、それだけで最後に見つかった労働者を移動させ、結果のリストから何かを削除しません。

このアプローチでは、ループを折り返しにすることもできます。

関連する問題