Поиск всех фрагментов, разделенных двумя элементами в Scala `List` - PullRequest
0 голосов
/ 29 января 2019

В Scala, как правильно выбрать элементы списка на основе положения двух элементов?Предположим, у меня есть список ниже, и я хотел бы выбрать все элементы от 2 до 7, включая их (примечание: не больше чем / меньше чем, но элементы, которые идут после 2 и до 7 в списке):

scala> val l = List(1, 14, 2, 17, 35, 9, 12, 7, 9, 40)
l: List[Int] = List(1, 14, 2, 17, 35, 9, 12, 7, 9, 40)

scala> def someMethod(l: List[Int], from: Int, to: Int) : List[Int] = {
     | // some code here
     | }
someMethod: (l: List[Int], from: Int, to: Int)List[Int]

scala> someMethod(l, 2, 7)
res0: List[Int] = List(2, 17, 35, 9, 12, 7)

Ожидаемый результат:

  • Для списков, которые не содержат 2 и / или 7: пустой список
  • Ввод: (1, 2, 2, 2, 3, 4, 7, 8);Выход: (2, 2, 2, 3, 4, 7)
  • Вход: (1, 2, 3, 4, 7, 7, 7, 8);Выход: (2, 3, 4, 7)
  • Вход: (1, 2, 3, 4, 7, 1, 2, 3, 5, 7, 8);Выход: ((2, 3, 4, 7), (2, 3, 5, 7))

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Жаль, что движки регулярных выражений работают только со строками, а не с общими списками - было бы очень хорошо, если бы вы могли найти все совпадения для чего-то вроде L.*?R с двумя произвольными разделителями L и R.Так как это не работает с регулярным выражением, вы должны создать небольшой автомат самостоятельно.Вот один из способов сделать это:

@annotation.tailrec 
def findDelimitedSlices[A](
  xs: List[A],
  l: A,
  r: A,
  revAcc: List[List[A]] = Nil
): List[List[A]] = {
  xs match {
    case h :: t => if (h == l) {
      val idx = xs.indexOf(r)
      if (idx >= 0) {
        val (s, rest) = xs.splitAt(idx + 1)
        findDelimitedSlices(rest, l, r, s :: revAcc)
      } else {
        revAcc.reverse
      }
    } else {
      findDelimitedSlices(t, l, r, revAcc)
    }
    case Nil => revAcc.reverse
  }
}

Ввод:

for (example <- List(
  List(1, 2, 2, 2, 3, 4, 7, 8),
  List(1, 2, 3, 4, 7, 7, 7, 8),
  List(1, 2, 3, 4, 7, 1, 2, 3, 5, 7, 8)
)) {
  println(findDelimitedSlices(example, 2, 7))
}

Ввод:

List(List(2, 2, 2, 3, 4, 7))
List(List(2, 3, 4, 7))
List(List(2, 3, 4, 7), List(2, 3, 5, 7))
0 голосов
/ 29 января 2019

Вы ищете slice:

@ l.slice(2, 7)
res1: List[Int] = List(2, 17, 35, 9, 12)

@ l.slice(2, 8)
res2: List[Int] = List(2, 17, 35, 9, 12, 7)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...