Итератор для добавления счетчика к повторным строкам в файле - PullRequest
0 голосов
/ 14 января 2020

Предположим, я пишу функцию Iterator[String] => Iterator[String] для добавления счетчика к смежным "повторным" строкам, например:

def foo(it: Iterator[String]): Iterator[String] = ???
foo(Iterator("a", "a", "b", "a", "a", "a", "c", "a")) // ("a", "a1", "b", "a", "a1", "a2", "c", "a")

Я пишу функцию для группировки всех смежных дубликатов (как в длине прогона кодирование) groupRepeated: Iterator[String] => Iterator[List[String]] и тогда я могу написать foo тривиально.

Теперь мне интересно, есть ли более простое решение. Что бы вы предложили?

PS Я бы предпочел решение, которое работает с TraversableOnce вместо Iterator.

Ответы [ 2 ]

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

Что-то вроде этого должно сделать это:

it.scanLeft (("", "", 0)) { 
 case ((pref, last, count), next) if next == pref => (pref, next + (count+1), count+1) 
 case (_, next) => (next, next, 0) 
}.drop(1)
 .map(_._2)
2 голосов
/ 14 января 2020

Как насчет этого?

def foo(it: Iterator[String]): Iterator[String] =
  new Iterator[String] {
    var currentElement: String = _
    var currentCount: Int = _

    override def hasNext: Boolean = it.hasNext

    override def next(): String = {
      val elem = it.next()

      if (elem == currentElement) {
        currentCount += 1

        s"${currentElement}${currentCount}"
      } else {
        currentElement = elem
        currentCount = 0

        elem
      }
    }
  }

Что работает, как и ожидалось:

foo(List("a", "a", "a", "b", "a", "a", "b", "b", "c").iterator).toList 
// res: List[String] = List("a", "a1", "a2", "b", "a", "a1", "b", "b1", "c") 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...