Scala извлекает соседей в списке, которые отличаются на 1 (Ints) - PullRequest
0 голосов
/ 25 августа 2018

В настоящее время я пытаюсь извлечь соседей из списка, которые отличаются на 1. Например, если бы у меня был такой список:

List(1,2,3,7,8,10,13,14)
//By extracting I want to get:
List(
    List(1,2,3),
    List(7,8),
    List(10),
    List(13,14)
    )

Я сам попробовал это сделать foldLeft, я чувствовал, что был близко, но пока так далеко. Может кто-нибудь мне помочь? Какие-либо предложения? ^^ Спасибо вам большое! :)

Ответы [ 3 ]

0 голосов
/ 25 августа 2018
  //First Part: Separates the list into ordered pairs with tail - head == 1
  val ls = List(1,2,3,7,8,10,13,14)

  val lb: ListBuffer[List[Int]] = new ListBuffer[List[Int]]()

  for (List(left,right) <- ls.sorted.sliding(2)) {
    if (right - left == 1) {
      lb += List(left, right)
    }else {
      if(!lb.flatten.toList.contains(left)) lb += List(left)
    }
  }

  println(lb.toList)

  //Second Part: Merges ordered pairs (x1, y1) and (x2, y2) when y1 == y2
  val finalLb: ListBuffer[List[Int]] = new ListBuffer[List[Int]]()

  for (List(left,right) <- lb.toList.sliding(2)) {
    if(left.tail.contains(right.head)) {
      finalLb += (left ++ right).distinct
    }else{
      finalLb += right
    }
  }

  println(finalLb.toList)

Выходы

First Part: List(List(1, 2), List(2, 3), List(7, 8), List(10), List(13, 14))
Second Part: List(List(1, 2, 3), List(7, 8), List(10), List(13, 14))
0 голосов
/ 25 августа 2018

Последовательные целые числа будут увеличиваться в соответствии с индексом списка, поэтому мы можем вычесть индекс, и они сформируют группы с одинаковым числом

val li = List(1, 2, 3, 7, 8, 10, 13, 14)
val groups = li.zipWithIndex.groupBy({case (e, i) => e - i})  // group numbers
groups.values.toList.map(_.map(_._1))  // drop indices and grouping keys

Примечание: они потеряют порядок неупорядоченного начального списка. Для вашего случая вы можете изменить порядок с .sortBy(_.head)

0 голосов
/ 25 августа 2018

Вот решение, использующее foldRight:

val oldList = List(1, 2, 3, 7, 8, 10, 13, 14)

val newList = oldList.foldRight[List[List[Int]]](Nil)((a, b) => b match {
  case (bh @ bhh :: _) :: bt if (bhh - a == 1) => (a :: bh) :: bt
  case _ => (a :: Nil) :: b
})

Таким образом, мы перебираем записи в обратном порядке и либо добавляем их к существующему списку заголовков, либо добавляем новый список заголовков в зависимости от того, является ли различие одним:

Nil
(14, ...) => (14 :: Nil) :: Nil
(13, ...) => (13 :: 14 :: Nil) :: Nil
(10, ...) => (10 :: Nil) :: (13 :: 14 :: Nil) :: Nil
...

Я давно не пользовался Scala, так что это может быть не лучшим решением, но я надеюсь, что вы поняли.

...