在 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
方法?
子问题:
- 此外,是否可以列出不严格递增的值?即从列表末尾删除元素,直到一个元素低于 300。
- 如果
List
/Seq
不可能,那么 IndexedSeq
就像 Vector
或 Array
解决方案
我选择@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 的元素时,您可以停止执行任何检查
我只想删除 List
(或 Seq
)的最后 少数 个元素,并避免解析所有元素(并避免对所有这些应用过滤功能)。
比方说,我有一个随机严格递增的值列表:
import scala.util.Random.nextInt
val r = (1 to 100).map(_ => nextInt(10)+1).scanLeft(0)(_+_)
我想删除大于 300 的元素。我可以这样做:
r.filter(_<300)
但是这个方法解析了整个列表。那么,是否可以只在一端过滤列表?类似于 filterRight
方法?
子问题:
- 此外,是否可以列出不严格递增的值?即从列表末尾删除元素,直到一个元素低于 300。
- 如果
List
/Seq
不可能,那么IndexedSeq
就像Vector
或Array
解决方案
我选择@elm 解决方案是因为它回答了一般列表的子问题,而不仅仅是(严格)增加的问题。
然而,
首先注意 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 的元素时,您可以停止执行任何检查