如何在 Scala 中快速编写“过滤掉满足给定函数的序列的第一个/最后 n 个元素”?
FilterNot 定义为:
def filterNot(p: A => Boolean): Repr
Run Code Online (Sandbox Code Playgroud)
所以我正在寻找这样的功能:
def filterNotFirst(p: A => Boolean, n: Int): Repr
Run Code Online (Sandbox Code Playgroud)
最好是这样太大的 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)
Run Code Online (Sandbox Code Playgroud)
如果n大于可用值的数量,则不会抛出异常:
scala> (0 to 15).filterNot(_ < 10).take(100)
res3: IndexedSeq[Int] = Vector(10, 11, 12, 13, 14, 15)
Run Code Online (Sandbox Code Playgroud)
如果你真的想要filterNotFirst一个方法,你可以自己定义它:
def filterNotFirst[A](elems: Seq[A])(p: A => Boolean, n: Int): Seq[A] =
elems.filterNot(p).take(n)
Run Code Online (Sandbox Code Playgroud)
甚至:
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
Run Code Online (Sandbox Code Playgroud)
进而:
scala> (0 to 15).filterNotFirst(_ < 10, 100)
res4: Seq[Int] = Vector(10, 11, 12, 13, 14, 15)
Run Code Online (Sandbox Code Playgroud)
我只是使用建议filterNot,并take在需要的地方,虽然。