Как написать в Scala коротко «отфильтровать первые / последние n элементов, удовлетворяющих заданной функции»? - PullRequest
1 голос
/ 15 января 2020

Как написать коротко в Scala "отфильтровать первые / последние n элементов последовательности, удовлетворяющих заданной функции"?

FilterNot не определено:

def filterNot(p: A => Boolean): Repr

Итак, я ' m ищет такую ​​функцию, как:

def filterNotFirst(p: A => Boolean, n: Int): Repr

Желательно, чтобы слишком большое значение n не создавало исключение.

1 Ответ

5 голосов
/ 15 января 2020

Библиотека коллекций Scala не предоставляет операции, которая делает именно это, но есть идиоматический способ записи c: объединить 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 там, где это необходимо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...