如何在Scala中缩短for-comprehension(退出它)?

4 浏览
0 Comments

如何在Scala中缩短for-comprehension(退出它)?

我有一段代码,如下所示:

val e2 = for (e <- elements if condition(expensiveFunction(e))) yield {
            expensiveFunction(e)
         }

其中条件在几个元素上为真,然后在所有剩余的元素上变为假。

不幸的是,这并不起作用(即使我忽略性能),因为我的elements是一个无限迭代器。

在for-comprehension中是否有一种使用\"break\"的方法,以便在满足某种条件时停止产生元素?否则,计算我的e2应该采用哪种scala惯用方式?

admin 更改状态以发布 2023年5月23日
0
0 Comments

scala> def compute(i: Int) = { println(s"f$i"); 10*i }
compute: (i: Int)Int
scala> for (x <- Stream range (0, 20)) yield compute(x)
f0
res0: scala.collection.immutable.Stream[Int] = Stream(0, ?)
scala> res0 takeWhile (_ < 100)
res1: scala.collection.immutable.Stream[Int] = Stream(0, ?)
scala> res1.toList
f1
f2
f3
f4
f5
f6
f7
f8
f9
f10
res2: List[Int] = List(0, 10, 20, 30, 40, 50, 60, 70, 80, 90)

编辑,另一个演示:

scala> def compute(i: Int) = { println(s"f$i"); 10*i }
compute: (i: Int)Int
scala> for (x <- Stream range (0, 20)) yield compute(x)
f0
res0: scala.collection.immutable.Stream[Int] = Stream(0, ?)
scala> res0 takeWhile (_ < 100)
res1: scala.collection.immutable.Stream[Int] = Stream(0, ?)
scala> res1.toList
f1
f2
f3
f4
f5
f6
f7
f8
f9
f10
res2: List[Int] = List(0, 10, 20, 30, 40, 50, 60, 70, 80, 90)
scala> Stream.range(0,20).map(compute).toList
f0
f1
f2
f3
f4
f5
f6
f7
f8
f9
f10
f11
f12
f13
f14
f15
f16
f17
f18
f19
res3: List[Int] = List(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190)
scala> Stream.range(0,20).map(compute).takeWhile(_ < 100).toList
f0
f1
f2
f3
f4
f5
f6
f7
f8
f9
f10
res4: List[Int] = List(0, 10, 20, 30, 40, 50, 60, 70, 80, 90)

0
0 Comments

你可以采用懒惰的方法:

val e2 = elements.toIterator                    
          .map(expensiveFunction)
          .takeWhile(result => result == true) // or just .takeWhile(identity)
// you may want to strict iterator, (e.g. by calling .toList) at the end

因此,您可以根据需要计算expensiveFunction,如果某个步骤上为false,则不会做不必要的工作。

0