斯卡拉 - 可以产生一个for循环多次使用?(Scala - can yield be used m

2019-06-26 04:05发布

一个例子:

val l = List(1,2,3)
val t = List(-1,-2,-3)

我可以做这样的事情?

for (i <- 0 to 10) yield (l(i)) yield (t(i))

基本上我想获得多个结果每次迭代。

Answer 1:

目前还不清楚你问什么 - 你希望多产量的语义是什么。 有一两件事,虽然是你可能永远都不想使用索引来浏览列表 - 每次调用T(i)为O(I)来执行。

所以这里有一个可能性,你可能会问了

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))

而这里的,你可能会问另一个可能性

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))

后者是只是语法糖

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))

第三种可能性是要他们交错

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)

这对语法糖

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)


Answer 2:

不,你不能使用多个产量条款,但也有变通办法。 例如:

for (i <- 0 to 10;
     r <- List(l(i), t(i)))
yield r

你可以换内涵,当然,但是这将导致元素的列表,我不相信这是你想要的清单窝。



Answer 3:

产量可以嵌套,这将导致...

for (i <- 0 to 3) yield {
  for (j <- 0 to 2) yield (i,j)
}

在矢量的矢量:

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)

平坦化的解决方案是语义上不同。



Answer 4:

下面是一个未知的,变化的数在一个未知的号码列表的元件的类型无关的解决方案:

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
}

对于2所列出它是过度设计。 你可以尽管叫它

   xproduct (List (l, t))


Answer 5:

显然不是。 我得到一个编译错误,当我尝试它。

它看起来像..产量是一个表达式。 你不能有两个收益率,因为这不是真正表达的一部分。

如果你想获得多个值,为什么没有产生他们作为一个元组或列表?

例如:

for( t <- List(1,2,3); l <- List(-1,-2,-3))
  yield (t, l)


Answer 6:

也许产量不走的最好方法? 也许简单数组追加可以在这里使用。



文章来源: Scala - can yield be used multiple times with a for loop?