Если вы не возражаете добавить какую-либо инфраструктуру для обработки функции groupedWhile
, вы можете украсть ответ Рекса Керра о расширении коллекции scala . Используйте раздел, который обрабатывает массив, во второй части ответа.
Тогда это бриз:
scala> vals.groupedWhile(_._2 == _._2).filter(_.head._2 == true).map{g =>
(g.head, g.last)}.foreach(println)
((0,true),(3,true))
((5,true),(6,true))
((8,true),(9,true))
Edit:
Я придумал решение, которое не требует groupedWhile
. Он основан на использовании Iterator.iterate
, который начинается с начального числа и неоднократно применяет функцию span
для извлечения следующей группы элементов, имеющих то же логическое свойство. В этом случае семя является кортежем следующей группы и остатком для обработки:
type Arr = Array[(Int, Boolean)] // type alias for easier reading
val res = Iterator.iterate[(Arr, Arr)]((Array(), vals)){ case (same, rest) =>
// repeatedly split in (same by boolean, rest of data)
// by using span and comparing against head
rest.span(elem => elem._2 == rest.head._2)
}.drop(1).takeWhile{ case (same, _) => // drop initial empty seed array
same.nonEmpty // stop when same becomes empty
}.collect{ case (same, _) if same.head._2 == true =>
// keep "true" groups and extract (first, last)
(same.head, same.last)
}.foreach(println) // print result
Который печатает тот же результат, что и выше. Обратите внимание, что span
для пустых массивов не вызывает предикат, поэтому мы не получим исключение для rest.head
, если rest пусто.