为了方便起见,我用整数代替日期,但原理是相同的。
val data = List(
("a","a", 10),
("a","b", 30),
("a","b", 11),
("a","b", 33),
("s","c", 37),
("a","c", 26),
("a","d", 22),
("m","a", 18),
("t","a", 15)
)
val sortedData = data.sortWith ((a,b)=> a._3 < b._3)
println(s"$sortedData")
val splitPass = sortedData.foldLeft(List[(String, String,Int)](), List[List[(String, String,Int)]](), sortedData.head._3){
case ((cl, acc, ld),nt) =>
if (nt._3-ld>3)
(List(nt), cl.reverse ::acc, nt._3)
else
(nt:: cl, acc, nt._3)
}
val (fl, fa, _) = splitPass
val res = (if (fl.isEmpty) fa else fl :: fa).reverse
println(s"$res")
这将返回已排序的列表:
List((a,a,10), (a,b,11), (t,a,15), (m,a,18), (a,d,22), (a,c,26), (a,b,30), (a,b,33), (s,c,37))
和结果列表:
List(List((a,a,10), (a,b,11)), List((t,a,15), (m,a,18)), List((a,d,22)), List((a,c,26)), List((a,b,30), (a,b,33)), List((s,c,37)))
这个程序的作用是对排序后的列表进行一次遍历,构建一个累加器,其中包括(当前组中的项目列表、已完成组的列表、最后添加项目的日期)。初始时,累加器包含两个空列表和列表中第一个项目的日期。
对于源列表中的每个项目,如果它与前一个项目接近,则将其添加到当前组;如果它与前一个项目相距较远,则关闭当前组并将其添加到已完成组的列表中,并将当前项目成为新列表中的第一个项目,当前项目的日期成为下一次检查的参考日期。如果您想在日期与当前组中最早日期不同时中断,只需将else分支更改为传递ld而不是nt._3。
最后,您需要将任何未完成的组添加到最终的组合集中。
两个“.reverse”是必要的,因为列表按照典型的函数式风格是反向构建的(因为这样更便宜),并在完成后被反转。
sortBy(_._3)
替代sortWith
- undefined