也許這樣的事情。代碼有點長,但適用於您的特定輸入。它也可以重構,因爲兩個部分函數幾乎相同。
case class Day(id: Int, name: String)
case class Shift(id: Int, dayId: Int)
case class Break(id: Int, shiftId: Int)
val day1 = Day(1, "xx")
val day2 = Day(2, "xx")
val day3 = Day(3, "xx")
val shift1 = Shift(1, 1)
val shift2 = Shift(2, 1)
val shift3 = Shift(3, 2)
val break1 = Break(1, 1)
val break2 = Break(2, 3)
val input = Seq(
((day1, Some(shift1)), Some(break1)),
((day1, Some(shift2)), None),
((day2, Some(shift3)), Some(break2)),
((day2, None), None)
)
type MyReturnType = (Day, Seq[(Shift, Seq[Break])])
def convert(input: Seq[((Day, Option[Shift]), Option[Break])]): Seq[MyReturnType] = {
input.foldLeft(Seq[MyReturnType]()) {
case (acc, ((day, Some(shift)), Some(break))) =>
val findExistingDay = acc.find { case (d, _) => d == day }
val seqWithoutDay = acc.filter { case (d, _) => d != day }
val addNewElementIfDayExists = findExistingDay.map { case (d, seq) =>
(d, seq :+(shift, Seq(break))) +: seqWithoutDay
}
val otherwiseCreateANewOne = addNewElementIfDayExists.getOrElse((day, Seq((shift, Seq(break)))) +: acc)
otherwiseCreateANewOne
case (acc, ((day, Some(shift)), None)) =>
val findExistingDay = acc.find { case (d, _) => d == day }
val seqWithoutDay = acc.filter { case (d, _) => d != day }
val addNewElementIfDayExists = findExistingDay.map { case (d, seq) =>
(d, seq :+(shift, Seq())) +: seqWithoutDay
}
val otherwiseCreateANewOne = addNewElementIfDayExists.getOrElse((day, Seq((shift, Seq()))) +: acc)
otherwiseCreateANewOne
case (acc, ((day, None), Some(break))) =>
??? //I don't know what should I do in this case, because you didn't provide an example
case (acc, ((day, None), None)) =>
acc
}
}
val convertResult: Seq[MyReturnType] = convert(input)
convertResult.foreach(println)
/* result:
(Day(2,xx),List((Shift(3,2),List(Break(2,3)))))
(Day(1,xx),List((Shift(1,1),List(Break(1,1))), (Shift(2,1),List())))
res0: Unit =()
*/
//if you need it in a specific order:
convertResult.sortBy(_._1.id).foreach(println)
/* result:
(Day(1,xx),List((Shift(1,1),List(Break(1,1))), (Shift(2,1),List())))
(Day(2,xx),List((Shift(3,2),List(Break(2,3)))))
res1: Unit =()
*/
//if you also need an empty day3, then you have to somehow group the all days. Maybe like this::
val allDays = List(day1, day2, day3)
val withEmptyDays: Seq[MyReturnType] = allDays.map(d => convertResult.find(_._1 == d).getOrElse((d, Seq())))
withEmptyDays.foreach(println)
/*
(Day(1,xx),List((Shift(1,1),List(Break(1,1))), (Shift(2,1),List())))
(Day(2,xx),List((Shift(3,2),List(Break(2,3)))))
(Day(3,xx),List())
res2: Unit =()
*/
val output = Seq(
(day1, Seq((shift1, Seq(break1)), (shift2, Seq()))),
(day2, Seq((shift3, Seq(break2)))),
(day3, Seq())
)
這當然是SCALA,你可以在一個簡潔的方式把它寫:
def convert(input: Seq[((Day, Option[Shift]), Option[Break])]): Seq[(Day, Seq[(Shift, Seq[Break])])] = {
def helper(acc:Seq[(Day, Seq[(Shift, Seq[Break])])], day:Day, shift:Shift, breaks:Seq[Break]) =
acc.find(_._1 == day).map(a =>(a._1, a._2 :+ (shift, breaks)) +: acc.filter(_._1 != day)).getOrElse((day, Seq((shift, breaks))) +: acc)
input.foldLeft(Seq[(Day, Seq[(Shift, Seq[Break])])]()) {
case (acc, ((day, Some(shift)), Some(break))) => helper(acc, day, shift, Seq(break))
case (acc, ((day, Some(shift)), None)) => helper(acc, day, shift, Seq())
case (acc, ((day, None), Some(break))) =>
???
case (acc, ((day, None), None)) =>
acc
}
}
我怎樣才能從我的輸入轉換到您指定的輸入? – ttt
@ttt看到我編輯的答案 – fusion
你也可以在convert方法中寫flatten,所以它會接受正確的格式並在裏面弄平。 – NieMaszNic