对于scala中的.map()内部的循环:返回类型是"单元"

时间:2015-07-06 13:19:00

标签: scala

编辑:我发现这个What is Scala's yield?(特别是第二个,最受欢迎的答案)在接受的答案解决了我的问题后非常有启发性。

==

我有一个HashMap,我想迭代它,对于每个键,使用for循环来创建新对象。

我试图获取这些新对象的列表,但我总是给予一个空的" Unit"序列。我想更好地理解我的代码的行为。

case class MyObject(one: String, two: String, three: Int)

val hm = new HashMap[String,Int]

hm += ("key" -> 3)
hm += ("key2" -> 4)

val newList = hm.map { case (key,value) =>
  for (i <- 0 until value) {
    new MyObject(key, "a string", i)
  }}.toSeq

结果:

newList:Seq[Unit] = ArrayBuffer((), ())

如果我不在.map()中使用任何for循环,我就有了我期待的结构类型:

val newList = hm.map { case (key,value) =>
    new MyObject(key, "a string", value)}.toSeq

结果:

 newList:Seq[MyObject] = ArrayBuffer(MyObject(key,host,3), MyObject(key2,host,4))

1 个答案:

答案 0 :(得分:7)

正如我在评论中提到的,您在yield声明中遗漏了map。如果您不包含yield关键字,那么您的理解纯粹是副作用,并且不会产生任何效果。将其更改为:

for (i <- 0 until value) yield {

现在,从这里开始,您将得到一个Seq[IndexedSeq[MyObject]]。如果您想最终得到Seq[MyObject],那么您可以flatten这样:

val newList = hm.map { case (key,value) =>
  for (i <- 0 until value) yield {
    MyObject(key, "a string", i)
  }}.toSeq.flatten
}

事实上(正如@KarolS所指出的那样),您可以将map替换为flatMap并在结尾删除明确的flatten,从而进一步缩短这一点:

val newList = hm.flatMap { case (key,value) =>
  for (i <- 0 until value) yield {
    MyObject(key, "a string", i)
  }}.toSeq
}