在 Scala 中仅过滤 list/iterable 的一侧

filtering only one side of a list/iterable in scala

我只想删除 List(或 Seq)的最后 少数 个元素,并避免解析所有元素(并避免对所有这些应用过滤功能)。

比方说,我有一个随机严格递增的值列表:

 import scala.util.Random.nextInt
 val r = (1 to 100).map(_ => nextInt(10)+1).scanLeft(0)(_+_)

我想删除大于 300 的元素。我可以这样做:

r.filter(_<300)

但是这个方法解析了整个列表。那么,是否可以只在一端过滤列表?类似于 filterRight 方法?

子问题:

解决方案

我选择@elm 解决方案是因为它回答了一般列表的子问题,而不仅仅是(严格)增加的问题。 然而, 的解决方案看起来更有效,因为它不执行 2 reverse

首先注意 SI-4247 dropWhile 但没有 dropRightWhile

不过,传达所需语义的简单实现,

def dropRightWhile[A](xs: Seq[A], p: A => Boolean) = 
  xs.reverse.dropWhile(p).reverse

或等效

implicit class OpsSeq[A](val xs: Seq[A]) extends AnyVal {
  def dropRightWhile(p: A => Boolean) = xs.reverse.dropWhile(p).reverse
}

您正在寻找类似 dropRightWhile 的东西,它在标准库 (but has been requested before) 中不存在。

我认为你最好的选择是:

r.takeWhile(_<300)

由于它是一个递增的值列表,当您第一次遇到大于 300 的元素时,您可以停止执行任何检查