За

val xs = (1 to 9).toArray

Мы можем группировать, например, каждые два последовательных элемента следующим образом,

xs.grouped(2)

Тем не менее, учитывая конечную последовательность значений, а именно, например,

val gr = Seq(3,2,1)

Как сгруппировать xs на основе gr так, чтобы

xs.grouped(gr)
res: Array(Array(1,2,3), Array(4,5), Array(6), Array(7,8,9))
1
elm 27 Окт 2015 в 11:56

2 ответа

Лучший ответ

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

def grouped[T](what: Seq[T], by: Seq[Int]) = {

  def go(left: Seq[T], nextBy: Int, acc: List[Seq[T]]): List[Seq[T]] = (left.length, by(nextBy % by.length)) match {
    case (n, sz) if n <= sz => left :: acc
    case (n, sz) => go(left.drop(sz), nextBy+1, left.take(sz) :: acc)
  }

  go(what, 0, Nil).reverse
}
1
Shadowlands 27 Окт 2015 в 09:11

Пожалуйста, рассмотрите следующее решение:

def groupBySeq[T](arr:Array[T], gr:Seq[Int]) = {
  val r = gr.foldLeft((arr, List[Array[T]]())) {
    case ((rest, acc), item) => (rest.drop(item), rest.take(item)::acc)
  }
  (r._1::r._2).reverse
}
2
Nyavro 27 Окт 2015 в 09:28