I cannot figure out why my function invokeAll does not give out the correct output/work properly. Any solutions? (No futures or parallel collections allowed and the return type needs to be Seq[Int])
def invokeAll(work: Seq[() => Int]): Seq[Int] = {
//this is what we should return as an output "return res.toSeq"
//res cannot be changed!
val res = new Array[Int](work.length)
var list = mutable.Set[Int]()
var n = res.size
val procedure = (0 until n).map(work =>
new Runnable {
def run {
//add the finished element/Int to list
list = work
}
}
)
val threads = procedure.map(new Thread(_))
threads.foreach(x => x.start())
threads.foreach (x => (x.join()))
res list
//this should be the final output ("return res.toSeq")
return res.toSeq
}
CodePudding user response:
OMG, I know a java programmer, when I see one :) Don't do this, it's not java!
val results: Future[Seq[Int]] = Future.traverse(work)
This is how you do it in scala.
This gives you a Future
with the results of all executions, that will be satisfied when all work is finished. You can use .map
, .flatMap
etc. to access and transform those results. For example
val sumOfAll: Future[Int] = results.map(_.sum)
Or (in the worst case, when you want to just give the result back to imperative code), you could block and wait on the future to get ahold of the actual result (don't do this unless you are absolutely desperate): Await.result(results, 1 year)
If you want the results as array, results.map(_.toArray)
will do that ... but you really should not: arrays aren't really a good choice for the vast majority of use cases in scala. Just stick with Seq
.
CodePudding user response:
The main problem in your code is that you are using fixed size array and trying to add some elements using
(concatenate
) operator: res list
. It produces new Seq
but you don't store it in some val
.
You could remove last line return res.toSeq
and see that res lest
will be return value. It will be your work.length
array of zeros res
with some list
sequence at the end. Try read more about scala collections most of them immutable and there is a good practice to use immutable data structures. In scala Arrays doesn't accumulate values using
operator in left operand. Array's in scala are fixed size.