I'm pretty sure this question might be duplicated, but I haven't come across the answer for this. Please pardon my ignorant knowledge of Scala. I'm pretty newbie.
My aim is to loop over two lists (with different length) and return List[List[Option[Double]]]
.
My code so far:
def getDoubles(symbol: String, year: Int): Option[Double] = {
return Some(140.0)
}
// this method loops over list of strings and range of time. returns list of list of Option[Double]
def checkList(CSV: List[String], time: Range): List[List[Option[Double]]] = {
// this variable is whats going to be returned at the end
var listOfLists = List[List[Option[Double]]]()
// So we are going to loop over our list and our time, and link each element in our list to all the elements in our time range
for {
i < -CSV
j < -time
// the method getDoubles is pretty long, so i just made another version simplfying my question.
// get doubles bascially returns Option of doubles
}
yield (listOfLists = getDoubles(j, i)::listOfLists)
return listOfLists
}
The above code, when I call it with more sophisticated data, it returns:
Vector(
Some(313.062468),
Some(27.847252),
Some(301.873641),
Some(42.884065),
Some(332.373186),
Some(53.509768)
)
But I want to return something like this:
List(
List(Some(313.062468), Some(27.847252)),
List(Some(301.873641), Some(42.884065)),
List(Some(332.373186), Some(53.509768))
)
How can I do this?
You don't need to use any mutable variables for this. First of all, you if you need a nested list, you need a nested for
. Then in yield
you should write how looks each element of the collection produced by this for
. It's not a loop body, you're not supposed to do any mutations there. The whole for
-expression is the resulting collection. Check Scala FAQ on "How does yield work?".
def checkList(csv: List[String], time: Range): List[List[Option[Double]]] = {
for {
symbol <- csv
} yield {
for {
year <- time.toList
} yield getDoubles(symbol, year)
}
}
For-comprehension is just a syntax sugar for a combination of map
, flatMap
andfilter
. In this case writing it with map
is more concise and very straightforward:
def checkList(csv: List[String], time: Range): List[List[Option[Double]]] = {
csv map { symbol =>
time map { year =>
getDoubles(symbol, year)
}
}
}
See also "What is Scala's yield?" question.