加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – foldLeft在Stream [布尔]中提前终止?

发布时间:2020-12-16 18:11:53 所属栏目:安全 来源:网络整理
导读:我有一个: val a : Stream[Boolean] = ... 当我将它折叠起来如下 val b = a.foldLeft(false)(_||_) 它会在流中找到第一个真值时终止吗?如果没有,我该怎么做? 解决方法 不,它不会提前终止.这很容易说明: val a : Stream[Boolean] = Stream.continually(tr
我有一个:

val a : Stream[Boolean] = ...

当我将它折叠起来如下

val b = a.foldLeft(false)(_||_)

它会在流中找到第一个真值时终止吗?如果没有,我该怎么做?

解决方法

不,它不会提前终止.这很容易说明:

val a : Stream[Boolean] = Stream.continually(true)
// won't terminate because the strea
val b = a.foldLeft(false)(_||_)

stew表明,在您的具体情况下,提前终止的简单解决方案是

val b = a.exists(identity).

更简单,这相当于:

val b = a.contains(true)

与上述不同的更通用的解决方案也适用,如果你真的需要折叠,是使用递归(请注意,这里我假设流是非空的,为简单起见):

def myReduce( s: Stream[Boolean] ): Boolean = s.head || myReduce( s.tail )
val b = myReduce(a)

现在,递归解决方案的有趣之处在于它如何在更通用的用例中使用,在这种情况下,您实际上需要以某种方式累积值(这是折叠的用途)并且仍然提前终止.假设您要使用add方法添加int流的值,该方法将以类似于||的方式提前“终止” (在这种情况下,如果左侧是> 100,则不评估其右侧):

def add(x: Int,y: => Int) = if ( x >= 100 ) x else x + y
val a : Stream[Int] = Stream.range(0,Int.MaxValue)
val b = a.foldLeft(0)(add(_,_))

最后一行不会终止,就像你的例子中一样.但你可以像这样解决它:

def myReduce( s: Stream[Int] ): Int = add( s.head,myReduce( s.tail ) )
val b = myReduce(a)

警告:这种方法有一个明显的缺点:myReduce在这里不是尾递归,这意味着如果迭代流的太多元素,它将会破坏你的堆栈.
还有另一种解决方案,它不会打击堆栈,这是:

val b = a.takeWhile(_ <= 100).foldLeft(0)(_ + _)

但是我担心我在主题方面走得太远,所以我现在最好停下来.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读