如何用Scala中的map替换yield?

时间:2012-01-08 23:01:48

标签: scala yield

如何删除此收益率?我想用地图而不是:

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

这可能吗?

谢谢!

祝你好运, 约翰

2 个答案:

答案 0 :(得分:13)

这很简单:

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

UPD

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)] = ...

答案 1 :(得分: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