List
のような与えられた
List(1, 2, 3, 4, 5, 6, 7)
それをn個のサブリストに分割し、ラウンドロビン方式で各リストにアイテムを配置するための最良の方法は何ですか?
たとえば、n = 3の場合、結果は次のようになります。
List(List(1, 4, 7), List(2, 5), List(3, 6))
コレクションAPIにこれを行うメソッドがあると思いましたが、見つからないようです。
上品なワンライナーのボーナスポイント;)
List
のような与えられた
List(1, 2, 3, 4, 5, 6, 7)
それをn個のサブリストに分割し、ラウンドロビン方式で各リストにアイテムを配置するための最良の方法は何ですか?
たとえば、n = 3の場合、結果は次のようになります。
List(List(1, 4, 7), List(2, 5), List(3, 6))
コレクションAPIにこれを行うメソッドがあると思いましたが、見つからないようです。
上品なワンライナーのボーナスポイント;)
scala> def round[T](l: List[T], n: Int) = (0 until n).map{ i => l.drop(i).sliding(1, n).flatten.toList }.toList
round: [T](l: List[T], n: Int)List[List[T]]
scala> round((1 to 7).toList, 3)
res4: List[List[Int]] = List(List(1, 4, 7), List(2, 5), List(3, 6))
簡単なワンライナーは次のとおりです。
scala> List.range(1, 10)
res11: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> res11.grouped(3).toList.transpose
res12: List[List[Int]] = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9))
残念ながら、リストが転置できない場合は機能しません。
scala> List.range(1, 8).grouped(3).toList.transpose
java.lang.IllegalArgumentException: transpose requires all collections have the
same size
次の方法を使用して転置可能にしてから、上記のアプローチを適用できます。
scala> def extend[A](xs: List[A], c: Int): List[Option[A]] = {
| val n = Stream.iterate(c)(c +).find(_ >= xs.length).get
| xs.map(Some(_)).padTo(n, None)
| }
extend: [A](xs: List[A], c: Int)List[Option[A]]
scala> List.range(1, 8)
res13: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
scala> extend(res13, 3).grouped(3).toList.transpose.map(_.flatten)
res14: List[List[Int]] = List(List(1, 4, 7), List(2, 5), List(3, 6))
まとめる:
scala> def round[A](xs: List[A], c: Int) = {
| val n = Stream.iterate(c)(c +).find(_ >= xs.length).get
| val ys = xs.map(Some(_)).padTo(n, None)
| ys.grouped(c).toList.transpose.map(_.flatten)
| }
round: [A](xs: List[A], c: Int)List[List[A]]
scala> round(List.range(1, 10), 3)
res16: List[List[Int]] = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9))
scala> round(List.range(1, 8), 3)
res17: List[List[Int]] = List(List(1, 4, 7), List(2, 5), List(3, 6))
ラウンドロビンにすることを気にしない場合は、次のことができます。
val list = List(1, 2, 3, 4, 5, 6, 7)
list.grouped(Math.ceil(list.size / 3))