Vielleicht so etwas
Die Umwandlung kann wie folgt vorgenommen werden. Der Code ist ein wenig lang, aber es funktioniert für Ihre spezifische Eingabe. Es kann auch umstrukturiert werden, weil zwei Teilfunktionen fast gleich sind.
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())
)
Natürlich ist das SCALA und Sie können es in prägnanter Weise schreiben:
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
}
}
Wie kann ich umwandeln von meinem Eingang mit dem Eingang von Ihnen angegebenen? – ttt
@ttt sehe meine bearbeitete Antwort – fusion
Sie könnten auch flach in der Convert-Methode schreiben, so würde es das richtige Format akzeptieren und die flatten innerhalb machen. – NieMaszNic