如何在 Scala 中快速编写"过滤掉满足给定函数的序列的前/后 n 个元素"?
过滤器不是定义的:
def filterNot(p: A => Boolean): Repr
所以我正在寻找这样的功能:
def filterNotFirst(p: A => Boolean, n: Int): Repr
最好使太大的 n 不会引发异常。
Scala 集合库没有提供完全做到这一点的操作,但有一种惯用的方法来编写它:将filter
或filterNot
和take
或takeRight
结合起来:
scala> val elems: Seq[Int] = 0 to 100
elems: Seq[Int] = Range 0 to 100
scala> elems.filterNot(_ < 10).take(5)
res0: Seq[Int] = Vector(10, 11, 12, 13, 14)
scala> elems.filterNot(_ < 10).takeRight(5)
res1: Seq[Int] = Vector(96, 97, 98, 99, 100)
如果n
大于可用值的数量,这不会引发异常:
scala> (0 to 15).filterNot(_ < 10).take(100)
res3: IndexedSeq[Int] = Vector(10, 11, 12, 13, 14, 15)
如果你真的想filterNotFirst
作为一个方法,你可以自己定义它:
def filterNotFirst[A](elems: Seq[A])(p: A => Boolean, n: Int): Seq[A] =
elems.filterNot(p).take(n)
甚至:
scala> implicit class FilterNotFirstOp[A](elems: Seq[A]) {
| def filterNotFirst(p: A => Boolean, n: Int): Seq[A] =
| elems.filterNot(p).take(n)
| }
defined class FilterNotFirstOp
然后:
scala> (0 to 15).filterNotFirst(_ < 10, 100)
res4: Seq[Int] = Vector(10, 11, 12, 13, 14, 15)
不过,我建议在需要时使用filterNot
和take
。