Scala - 可以在 for 循环中多次使用 yield 吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1140164/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Scala - can yield be used multiple times with a for loop?
提问by Monis Iqbal
An example:
一个例子:
val l = List(1,2,3)
val t = List(-1,-2,-3)
Can I do something like this?
我可以做这样的事情吗?
for (i <- 0 to 10) yield (l(i)) yield (t(i))
Basically I want to yield multiple results for every iteration.
基本上我想为每次迭代产生多个结果。
回答by James Iry
It's not clear what you're asking for - what you expect the semantics of multiple yield to be. One thing, though, is that you probably never want to use indexes to navigate a list - each call to t(i) is O(i) to execute.
目前尚不清楚您在要求什么 - 您期望多重收益的语义是什么。但是,有一件事是您可能永远不想使用索引来导航列表 - 对 t(i) 的每次调用的执行时间都是 O(i)。
So here's one possibility that you might be asking for
所以这是您可能要求的一种可能性
scala> val l = List(1,2,3); val t = List(-1,-2,-3)
l: List[Int] = List(1, 2, 3)
t: List[Int] = List(-1, -2, -3)
scala> val pairs = l zip t
pairs: List[(Int, Int)] = List((1,-1), (2,-2), (3,-3))
And here's another possibility that you might be asking for
这是您可能要求的另一种可能性
scala> val crossProduct = for (x <- l; y <- t) yield (x,y)
crossProduct: List[(Int, Int)] = List((1,-1), (1,-2), (1,-3), (2,-1), (2,-2), (2,-3), (3,-1), (3,-2), (3,-3))
The later is just syntactic sugar for
后者只是语法糖
scala> val crossProduct2 = l flatMap {x => t map {y => (x,y)}}
crossProduct2: List[(Int, Int)] = List((1,-1), (1,-2), (1,-3), (2,-1), (2,-2), (2,-3), (3,-1), (3,-2), (3,-3))
A third possibility is you want to interleave them
第三种可能是你想交错它们
scala> val interleaved = for ((x,y) <- l zip t; r <- List(x,y)) yield r
interleaved: List[Int] = List(1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10)
That's syntax sugar for
这是语法糖
scala> val interleaved2 = l zip t flatMap {case (x,y) => List(x,y)}
interleaved2: List[Int] = List(1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10)
回答by Daniel C. Sobral
No, you can't use multiple yield clauses, but there are work-arounds. For example:
不,您不能使用多个 yield 子句,但有变通方法。例如:
for (i <- 0 to 10;
r <- List(l(i), t(i)))
yield r
You can nest for-comprehensions, of course, but that would result in a list of lists of elements, which I don't believe is what you want.
当然,您可以嵌套理解,但这会导致元素列表的列表,我认为这不是您想要的。
回答by user unknown
Yields can be nested, which would result ...
产量可以嵌套,这将导致......
for (i <- 0 to 3) yield {
for (j <- 0 to 2) yield (i,j)
}
in a Vector of Vector:
在 Vector of Vector 中:
scala.collection.immutable.IndexedSeq[scala.collection.immutable.IndexedSeq[(Int, Int)]]
= Vector(Vector((0,0), (0,1), (0,2)), Vector((1,0), (1,1), (1,2)), Vector((2,0), (2,1), (2,2)), Vector((3,0), (3,1), (3,2)))
for (i <- 0 to 3;
j <- 0 to 2) yield (i,j)
The flattened solution is semantically different.
扁平化的解决方案在语义上是不同的。
回答by user unknown
Here is a type-agnostic solution for an unknown, varying number of elements in a unknown number of lists:
这是一个类型不可知的解决方案,用于未知数量的列表中的未知、变化数量的元素:
def xproduct (xx: List [List[_]]) : List [List[_]] =
xx match {
case aa :: bb :: Nil =>
aa.map (a => bb.map (b => List (a, b))).flatten
case aa :: bb :: cc =>
xproduct (bb :: cc).map (li => aa.map (a => a :: li)).flatten
case _ => xx
}
For 2 Lists it is overengineered. You could although call it
对于 2 个列表,它是过度设计的。你可以尽管称之为
xproduct (List (l, t))
回答by Christopher
Apparently not. I get a compile error when I try it.
显然不是。我在尝试时遇到编译错误。
It looks like for .. yield is an expression. You can't have two yields, since that's not really part of the expression.
看起来 for .. yield 是一个表达式。你不能有两个产量,因为那不是表达式的真正组成部分。
If you want to yield multiple values, why not yield them as a tuple or a list?
如果您想产生多个值,为什么不将它们作为元组或列表产生呢?
For example:
例如:
for( t <- List(1,2,3); l <- List(-1,-2,-3))
yield (t, l)
回答by Geo
Maybe yieldis not the best way to go? Perhaps simple array appending could be used here.
也许yield不是最好的方法?也许这里可以使用简单的数组附加。

