如何在Scala中使用map替换yield?

6

我该如何去掉这些yield?我想使用map代替:

val cols = for(x <- 0 to 6) yield for(y <- 0 to 5) yield apply(x, y)

这可能吗?

谢谢!

最好的祝福, 约翰


4
通常情况下,“for (x <- seq) yield f(x)”被翻译为“seq.map(x => f(x))”。 - user166390
9
不是回答你的问题,但以防万一:val cols = Vector.tabulate(7,6)(apply) - huynhjl
2个回答

13

这很简单:

val cols = (0 to 6).map(x => (0 to 5).map( y => apply(x,y)))

更新

map 可能会有变化。如果您想要一个没有嵌套结构的扁平对象,最好使用 flatMap 而不是仅使用 map

def apply(x: Int, y: Int) = (x,y)
scala> val cols = (0 to 6).map(x => (0 to 5).map( y => apply(x,y)))
//cols: scala.collection.immutable.IndexedSeq[scala.collection.immutable.IndexedSeq[(Int, Int)]] =  ...

scala> val cols = (0 to 6).flatMap(x => (0 to 5).map( y => apply(x,y)))
//cols: scala.collection.immutable.IndexedSeq[(Int, Int)] = ...

或者在最后将结果拉平:

scala> val cols = (0 to 6).map(x => (0 to 5).map( y => apply(x,y))).flatten
//cols: scala.collection.immutable.IndexedSeq[(Int, Int)] = ...

我还有一个问题。当我使用这段代码并打印这个cols println("cols: "+cols)时,我会得到2行。为什么? - user1137701
@user1137701,您能否请具体说明您期望的输出以及实际得到的结果?我怀疑这是因为我使用了map保存了内部结构,而没有使用flatMap返回未嵌套的对象。 - om-nom-nom
嘿,是的,我已经得到了这个: code val array = Array.fill(7)(Array.fill(6)(None:Option[Coin]))def apply(x: Int, y: Int):Option[Coin] = if (0 <= x && x < 7 && 0 <= y && y < 6) array(x)(y) else Noneval cols = (0 until 7).map(x => (0 until 6).map( y => apply(x,y))) code 当我打印cols时,我会得到两次... - user1137701

6
当您有多个生成器时,最里面的一个被翻译成map,其余的被翻译成flatMap。(在您的情况下,这些不是嵌套的生成器。)
以下示例可能会有所帮助:
scala> val xs, ys, zs = Vector(1, 4, 5)
xs: scala.collection.immutable.Vector[Int] = Vector(1, 4, 5)
ys: scala.collection.immutable.Vector[Int] = Vector(1, 4, 5)
zs: scala.collection.immutable.Vector[Int] = Vector(1, 4, 5)

scala> for {
     |   x <- xs
     |   y <- ys
     |   z <- zs
     | } yield (x, y, z)
res0: scala.collection.immutable.Vector[(Int, Int, Int)] = Vector((1,1,1), (1,1,4), (1,1,5), (1,4,1), (1,4,4), (1,4,5), (1,5,1), (1,5,4), (1,5,5), (4,1,1), (4,1,4), (4,1,5), (4,4,1), (4,4,4), (4,4,5), (4,5,1), (4,5,4), (4,5,5), (5,1,1), (5,1,4), (5,1,5), (5,4,1), (5,4,4), (5,4,5), (5,5,1), (5,5,4), (5,5,5))

scala> xs flatMap { x =>
     |   ys flatMap { y =>
     |     zs map { z =>
     |       (x, y, z)
     |     }
     |   }
     | }
res1: scala.collection.immutable.Vector[(Int, Int, Int)] = Vector((1,1,1), (1,1,4), (1,1,5), (1,4,1), (1,4,4), (1,4,5), (1,5,1), (1,5,4), (1,5,5), (4,1,1), (4,1,4), (4,1,5), (4,4,1), (4,4,4), (4,4,5), (4,5,1), (4,5,4), (4,5,5), (5,1,1), (5,1,4), (5,1,5), (5,4,1), (5,4,4), (5,4,5), (5,5,1), (5,5,4), (5,5,5))

scala> res0 == res1
res2: Boolean = true

scala> for {
     |   x <- xs
     |   y <- ys
     | } yield for {
     |   z <- zs
     | } yield (x, y, z)
res3: scala.collection.immutable.Vector[scala.collection.immutable.Vector[(Int, Int, Int)]] = Vector(Vector((1,1,1), (1,1,4), (1,1,5)), Vector((1,4,1), (1,4,4), (1,4,5)), Vector((1,5,1), (1,5,4), (1,5,5)), Vector((4,1,1), (4,1,4), (4,1,5)), Vector((4,4,1), (4,4,4), (4,4,5)), Vector((4,5,1), (4,5,4), (4,5,5)), Vector((5,1,1), (5,1,4), (5,1,5)), Vector((5,4,1), (5,4,4), (5,4,5)), Vector((5,5,1), (5,5,4), (5,5,5)))

scala> xs flatMap { x =>
     |   ys map { y =>
     |     zs map { z =>
     |       (x, y, z)
     |     }
     |   }
     | }
res4: scala.collection.immutable.Vector[scala.collection.immutable.Vector[(Int, Int, Int)]] = Vector(Vector((1,1,1), (1,1,4), (1,1,5)), Vector((1,4,1), (1,4,4), (1,4,5)), Vector((1,5,1), (1,5,4), (1,5,5)), Vector((4,1,1), (4,1,4), (4,1,5)), Vector((4,4,1), (4,4,4), (4,4,5)), Vector((4,5,1), (4,5,4), (4,5,5)), Vector((5,1,1), (5,1,4), (5,1,5)), Vector((5,4,1), (5,4,4), (5,4,5)), Vector((5,5,1), (5,5,4), (5,5,5)))

scala> res3 == res4
res5: Boolean = true

scala> for {
     |   x <- xs
     | } yield for {
     |   y <- ys
     |   z <- zs
     | } yield (x, y, z)
res6: scala.collection.immutable.Vector[scala.collection.immutable.Vector[(Int, Int, Int)]] = Vector(Vector((1,1,1), (1,1,4), (1,1,5), (1,4,1), (1,4,4), (1,4,5), (1,5,1), (1,5,4), (1,5,5)), Vector((4,1,1), (4,1,4), (4,1,5), (4,4,1), (4,4,4), (4,4,5), (4,5,1), (4,5,4), (4,5,5)), Vector((5,1,1), (5,1,4), (5,1,5), (5,4,1), (5,4,4), (5,4,5), (5,5,1), (5,5,4), (5,5,5)))

scala> xs map { x =>
     |   ys flatMap { y =>
     |     zs map { z =>
     |       (x, y, z)
     |     }
     |   }
     | }
res7: scala.collection.immutable.Vector[scala.collection.immutable.Vector[(Int, Int, Int)]] = Vector(Vector((1,1,1), (1,1,4), (1,1,5), (1,4,1), (1,4,4), (1,4,5), (1,5,1), (1,5,4), (1,5,5)), Vector((4,1,1), (4,1,4), (4,1,5), (4,4,1), (4,4,4), (4,4,5), (4,5,1), (4,5,4), (4,5,5)), Vector((5,1,1), (5,1,4), (5,1,5), (5,4,1), (5,4,4), (5,4,5), (5,5,1), (5,5,4), (5,5,5)))

scala> res6 == res7
res8: Boolean = true

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接