任何解决方案应该在开始时grouped
,其中砍下收集成片:
scala> val g = "ABCDEFGHIJKLMN".grouped(5)
g: Iterator[String] = non-empty iterator // Will return "ABCDE", then "FGHIJ", then "KLMN"
然后,我们把一切都成一个列表,所以我们可以很容易地拿尾巴:
scala> val l = g.map(_.toList).toList
List[List[Char]] = List(List(A, B, C, D, E), List(F, G, H, I, J),
List(K, L, M, N))
现在我们通过采取连续的尾巴收集这些,停止时没有什么留下的:
scala> val i = Iterator.iterate(l)(_.map(_ drop 1).filter(_.nonEmpty)).takeWhile(_.nonEmpty)
i: Iterator[List[List[Char]]] = non-empty iterator
// List(List(A, B, C, D, E), List(F, G, H, I, J), List(K, L, M, N))
// List(List(B, C, D, E), List(G, H, I, J), List(L, M, N))
// List(List(C, D, E), List(H, I, J), List(M, N))
// List(List(D, E), List(I, J), List(N))
// List(List(E), List(J))
这看起来大,但由于我们使用List
,短名单共享与较长的内存,所以它不是一个可怕的?在大小(N^2)爆炸。但是,我们真的只是想的头上,我们已经过滤掉一切空的,所以我们就可以做到这一点:
scala> val h = i.map(_.map(_.head))
h: Iterator[List[Char]] = non-empty iterator
// List(A, F, K)
// List(B, G, L)
// List(C, H, M)
// List(D, I, N)
// List(E, J)
终于从一个迭代器转换为严格的收集和扁平化:
scala> val ans = h.toList.flatten
ans: List[Char] = List(A, F, K, B, G, L, C, H, M, D, I, N, E, J)
(如果您想要返回String
,请添加mkString
)。
请注意,临时变量仅用于解释清楚。如果你想把它全部写在一行上,你可以。 (这会是一个相当长的线。)
(另请注意,如果您例如打印出的迭代器,它们会消耗掉。)
这是在一个大的一举:
("ABCDEFGHIJKLMN".grouped(5).map(_.toList).toList match {
case l => Iterator.iterate(l)(_.map(_ drop 1).filter(_.nonEmpty)).takeWhile(_.nonEmpty)
}).map(_.map(_.head)).toList.flatten
但这是非常不透明的,所以把东西传播出去留出评论空间是一个好主意。
谢谢,转矩只能在矩形矩阵上工作吗?如果输入seq只能达到'M',那么组函数会产生三个大小为5-5-3的列表? – Zuriar
'.transpose'如果集合不全都具有相同的长度,则会引发异常(如果发生这种情况,您可能需要查找'.padTo')。 – Marth
@ user3231690然后它将释放'IllegalArgumentException'。这是你的问题吗? –