Как сложить двух соседей в списке в Scala - PullRequest
0 голосов
/ 24 июня 2018

Если у вас есть один список целых чисел в Scala, и вы хотите перебрать его, суммировать каждые два соседа с одинаковым значением и вернуть его в виде списка, как один из них сделает это?

Так, например:

List(4, 4, 2, 6) => List(8, 2, 6)

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

def sumSameNeighbours: List[Int] => List[Int] = {
  ls match {
    case l1::l2:ls => l1 == l2
  }
}

Это то, о чем я могу думать.

РЕДАКТИРОВАТЬ: Как бы мне пришлось изменить код, чтобы выполнять итерацию справа налево, а не слева направо?

Так что, например это было бы:

List(2, 2, 2, 6, 4) => List(2, 4, 6, 4)

вместо

List(2, 2, 2, 6, 4) => List(4, 2, 6, 4)

Ответы [ 3 ]

0 голосов
/ 24 июня 2018

Примечание: Исходя из уточнения спецификаций окончательного ОП, этот ответ не совсем соответствует требованиям вопроса.

Вот решение с использованием List.grouped(2):

list.grouped(2).toList
  .flatMap {
    case List(a, b) if a == b => List(a + b)
    case l => l
  }

Идея состоит в группировании последовательных элементов по паре.Если пара содержит одинаковые элементы, мы возвращаем их сумму в flatMaped, а в противном случае оба элемента остаются нетронутыми.

List(4, 4, 2, 6) => List(8, 2, 6)
List(2, 4, 4, 2, 6) => List(2, 4, 4, 2, 6)
List(2) => List(2)
List(9, 4, 4, 4, 2, 6) => List(9, 4, 8, 2, 6)
0 голосов
/ 25 июня 2018

Другой способ использования foldRight, который я считаю хорошим значением по умолчанию для такого рода обхода коллекции при создании новой:

list.foldRight(List.empty[Int]) {
  case (x, y :: tail) if x == y => (x + y) :: tail
  case (x, list) => x :: list
}

Выход List(2, 2, 2, 6, 4) равен List(2, 4, 6, 4) по запросу.

Главное, что я не понял из ваших примеров, это то, каким должен быть вывод, если суммирование создает новых соседей: List(8, 4, 2, 2) должен превратиться в List(8, 4, 4) или List(16)? Это производит второй.

0 голосов
/ 24 июня 2018

Это довольно близко к вашему предложению и, кажется, в основном работает:

import scala.annotation.tailrec

def sumSameNeighbors( ls : List[Int] ) : List[Int] = {
  @tailrec
  def walk( unsummed : List[Int], reverseAccum : List[Int] ) : List[Int] = {
    unsummed match {
      case a :: b :: rest if a == b => walk( rest, a + b :: reverseAccum )
      case a :: rest                => walk( rest, a :: reverseAccum )
      case Nil                      => reverseAccum.reverse
    }
  }
  walk( ls, Nil )
}
...