Reputation: 6003
case class Test(dayOfWeek:Int,b:Int=Random.nextInt)
val data=(3 to 100).map(_ % 7).map(Test(_))
how to split the data into groups, each group have one week's data, if a week is not complete, also have a group. So the group should be
Group 1: (3,4,5,6) // the number here is the dayOfWeek
Group 2: (0,1,2,3,4,5,6)
Group 3: (0,1,2,3,4,5,6)
...
last Group:(0,1,2)
Upvotes: 4
Views: 554
Reputation: 1382
Here is a recursive version that works on general sequences and now requires a weekDay
function.
def groupByWeek[T](s: Seq[T], maxDay: Int = 6, weekDay: T => Int) = {
@scala.annotation.tailrec
def recurse(r: Seq[T], results: Seq[Seq[T]]): Seq[Seq[T]] =
r.splitAt(r.indexWhere(item => weekDay(item) == maxDay)) match {
case (hd, tl) if (hd.isEmpty && tl.isEmpty) => results
case (hd, tl) if (hd.isEmpty) => results :+ tl
case (hd, tl) => recurse(tl.tail, results :+ (hd :+ tl.head))
}
recurse(s,Seq.empty)
}
}
Called like this:
val weeks = groupByWeek(data, weekDay = (x:Test) => x.dayOfWeek)
And you can see the groups:
println(weeks.zipWithIndex.map {
case (week, i) => s"Group $i: (${week.map(_.dayOfWeek).mkString(",")})"
}.mkString("\n"))
Which outputs:
Group 0: (3,4,5,6)
Group 1: (0,1,2,3,4,5,6)
Group 2: (0,1,2,3,4,5,6)
[snip]
Group 12: (0,1,2,3,4,5,6)
Group 13: (0,1,2,3,4,5,6)
Group 14: (0,1,2)
Upvotes: 2
Reputation: 8534
Scala's collections are really powerful, this should do it in a couple of lines:
val (firstWeek, nextWeeks) = data.span(_.dayOfWeek != 0)
val weeks = (firstWeek :: nextWeeks.grouped(7).toList).dropWhile(_.isEmpty)
Look at the doc for span
and grouped
here.
println(weeks.zipWithIndex.map {
case (week, i) => s"Group $i: (${week.map(_.dayOfWeek).mkString(",")})"
}.mkString("\n"))
outputs:
Group 0: (3,4,5,6)
Group 1: (0,1,2,3,4,5,6)
Group 2: (0,1,2,3,4,5,6)
[snip]
Group 12: (0,1,2,3,4,5,6)
Group 13: (0,1,2,3,4,5,6)
Group 14: (0,1,2)
Upvotes: 4
Reputation: 52681
You can do it with a fold:
case class Test(dayOfWeek: Int, b: Int = scala.util.Random.nextInt)
val data = (3 to 100).map(_ % 7).map(Test(_))
val spans =
data.foldLeft(Vector(Vector.empty[Test])) {
case (zs :+ z, e) =>
if (e.dayOfWeek == 0)
if (z.nonEmpty)
(zs :+ z) :+ Vector(e)
else
zs :+ Vector(e)
else
zs :+ (z :+ e)
}
for ((g, i) <- spans.zipWithIndex) {
println(f"Group $i: (${g.map(_.dayOfWeek).mkString(",")})")
}
Output:
Group 0: (3,4,5,6)
Group 1: (0,1,2,3,4,5,6)
Group 2: (0,1,2,3,4,5,6)
Group 3: (0,1,2,3,4,5,6)
Group 4: (0,1,2,3,4,5,6)
Group 5: (0,1,2,3,4,5,6)
Group 6: (0,1,2,3,4,5,6)
Group 7: (0,1,2,3,4,5,6)
Group 8: (0,1,2,3,4,5,6)
Group 9: (0,1,2,3,4,5,6)
Group 10: (0,1,2,3,4,5,6)
Group 11: (0,1,2,3,4,5,6)
Group 12: (0,1,2,3,4,5,6)
Group 13: (0,1,2,3,4,5,6)
Group 14: (0,1,2)
Upvotes: 2