编辑:我发现这个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))
答案 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
}