bin*_*ADa 5 collections functional-programming scala
我想在序列中聚合兼容元素,即将a转换Seq[T]为Seq[Seq[T]]每个子序列中的元素彼此兼容的同时保留原始seq顺序,例如从
case class X(i: Int, n: Int) {
def canJoin(that: X): Boolean = this.n == that.n
override val toString = i + "." + n
}
val xs = Seq(X(1, 1), X(2, 3), X(3, 3), X(4, 3), X(5, 1), X(6, 2), X(7, 2), X(8, 1))
/* xs = List(1.1, 2.3, 3.3, 4.3, 5.1, 6.2, 7.2, 8.1) */
Run Code Online (Sandbox Code Playgroud)
想得到
val js = join(xs)
/* js = List(List(1.1), List(2.3, 3.3, 4.3), List(5.1), List(6.2, 7.2), List(8.1)) */
Run Code Online (Sandbox Code Playgroud)
我试图以功能的方式做到这一点,但我中途陷入困境:
def split(seq: Seq[X]): (Seq[X], Seq[X]) = seq.span(_ canJoin seq.head)
def join(seq: Seq[X]): Seq[Seq[X]] = {
var pp = Seq[Seq[X]]()
var s = seq
while (!s.isEmpty) {
val (p, r) = split(s)
pp :+= p
s = r
}
pp
}
Run Code Online (Sandbox Code Playgroud)
随着split我的满意,但join似乎有点太长了.
在我看来,这是一项标准任务.这引出了我的问题:
def join(xs: Seq[X]): Seq[Seq[X]] = {
@annotation.tailrec
def jointr(pp: Seq[Seq[X]], rem: Seq[X]): Seq[Seq[X]] = {
val (p, r) = split(rem)
val pp2 = pp :+ p
if (r.isEmpty) pp2 else jointr(pp2, r)
}
jointr(Seq(), xs)
}
Run Code Online (Sandbox Code Playgroud)
def join(seq: Seq[X]): Seq[Seq[X]] = {
if (seq.isEmpty) return Seq()
val (p,r) = split(seq)
Seq(p) ++ join(r)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
252 次 |
| 最近记录: |