Wie erhalte ich mit Scala eine Liste von Tupeln, die Start- und Endindizes von Unterlisten innerhalb einer anderen Liste von Ganzzahlen enthalten?
Betrachten Sie diese Liste:
val xs = List(3, 1, 1, 3, 5, 4, 4, 5)
Es gibt zwei Unterlisten, die mit derselben Zahl beginnen und enden und kleinere Zahlen dazwischen haben - 3, 1, 1, 3
und 5, 4, 4, 5
.
Ich möchte die Anfangs- und Endindizes dieser Unterlisten in einer Liste von Tupeln sammeln. Basierend auf dem obigen Beispiel wäre diese Liste:
List[(Int, Int)]((0, 3), (4, 7))
.. weil die erste Teilmenge bei Index 0 beginnt und bei 3 endet und die zweite die Indizes 4 und 7 hat.
Was wäre eine elegante Scala-Funktion, die dies tut?
Bearbeiten: Ich kenne den zwingenden Weg, dies mit var
s und for-Schleifen zu tun . Ich bin daran interessiert, eine elegante funktionale Lösung für dieses Problem zu finden.
Hier ist eine "Einzeiler"-Lösung:
xs.zipWithIndex
.groupBy(_._1)
.mapValues(_.map(_._2).combinations(2).map(c => (c(0), c(1))).toList)
.toList
.flatMap { case (x, intervals) =>
intervals.filter{ case (a, b) => xs.slice(a, b).exists(_ < x)}
}
produziert:
List((4,7), (0,3))
Eine hoffentlich etwas lesbarere Version mit sinnvoll benannten Zwischenergebnissen:
val numbersToIndices = xs.zipWithIndex.groupBy(_._1).mapValues(_.map(_._2))
val groupedIntervalsAsLists = numbersToIndices.mapValues(_.combinations(2).toList)
val groupedIntervals = intervalsAsLists.mapValues(_.map(v => (v(0), v(1)))).toList
val valleys = for {
(x, intervals) <- groupedIntervals
(a, b) <- intervals
if xs.slice(a, b).exists(_ < x)
} yield (a, b)
println(valleys)
wieder findet
List((4,7), (0,3))
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen