如何创建选项列表列表[双]用于循环Scala

时间:2016-11-16 00:49:31

标签: scala for-comprehension

我很确定这个问题可能会重复,但我还没有找到答案。请原谅我对斯卡拉的无知知识。我是新手。

我的目标是循环两个列表(长度不同)并返回List[List[Option[Double]]]

到目前为止我的代码:

 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
 }

上面的代码,当我用更复杂的数据调用它时,它返回:

Vector(
  Some(313.062468), 
  Some(27.847252), 
  Some(301.873641), 
  Some(42.884065), 
  Some(332.373186), 
  Some(53.509768)
)

但我想回复这样的事情:

List(
  List(Some(313.062468), Some(27.847252)),
  List(Some(301.873641), Some(42.884065)),
  List(Some(332.373186), Some(53.509768))
)

我该怎么做?

1 个答案:

答案 0 :(得分:3)

您不需要为此使用任何可变变量。首先,如果您需要嵌套列表,则需要嵌套for。然后在yield中,您应该编写如何查看此for生成的集合的每个元素。它不是一个循环体,你不应该在那里做任何突变。整个for - 表达式是生成的集合。在"How does yield work?"上查看Scala常见问题解答。

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只是mapflatMapfilter组合的语法糖。在这种情况下,使用map编写它更简洁,更直接:

def checkList(csv: List[String], time: Range): List[List[Option[Double]]] = {
  csv map { symbol =>
    time map { year =>
      getDoubles(symbol, year)
    }
  }
}

另见"What is Scala's yield?"问题。