Angesichts der folgenden Scala-Liste:
val l = List(List("a1", "b1", "c1"), List("a2", "b2", "c2"), List("a3", "b3", "c3"))
Wie bekomme ich:
List(("a1", "a2", "a3"), ("b1", "b2", "b3"), ("c1", "c2", "c3"))
Da zip nur zum Kombinieren von zwei Listen verwendet werden kann, müssten Sie die Hauptliste irgendwie iterieren / reduzieren. Es überrascht nicht, dass Folgendes nicht funktioniert:
scala> l reduceLeft ((a, b) => a zip b)
<console>:6: error: type mismatch;
found : List[(String, String)]
required: List[String]
l reduceLeft ((a, b) => a zip b)
Irgendwelche Vorschläge, wie man das macht? Ich glaube, ich vermisse einen sehr einfachen Weg, dies zu tun.
Update: Ich suche nach einer Lösung, die eine Liste von N Listen mit jeweils M Elementen erstellt und eine Liste von M TupelNs erstellt.
Update 2: Wie sich herausstellt, ist es für meinen speziellen Anwendungsfall besser, eine Liste mit Listen zu haben, als eine Liste mit Tupeln. Daher akzeptiere ich die Antwort von Kürbis. Es ist auch das einfachste, da es eine native Methode verwendet.
scala
functional-programming
list
zip
pr1001
quelle
quelle
Antworten:
Ich glaube nicht, dass es möglich ist, eine Liste von Tupeln beliebiger Größe zu erstellen, aber die Transponierungsfunktion macht genau das, was Sie brauchen, wenn es Ihnen nichts ausmacht, stattdessen eine Liste von Listen zu erhalten.
quelle
HList
s und dergleichen.Zum späteren Nachschlagen.
quelle
zipped
ist keine Funktion vonList
.zipped
ist in Scala 2.13 veraltet. in 2.13, dol1.lazyZip(l2).lazyZip(l3).toList
Dieser Code wird also nicht die Anforderungen des OP erfüllen, und zwar nicht nur, weil dies ein vier Jahre alter Thread ist, sondern er beantwortet auch die Titelfrage, und vielleicht findet ihn sogar jemand nützlich.
So komprimieren Sie 3 Sammlungen:
quelle
as zip bs zip cs zip ds map { case ((a,b),c)} map {case ((a,b),c,d)=>(a,b,c,d)}
as zip bs zip cs zip ds map {case (((a,b),c),d)=>(a,b,c,d) }
Ja, mit zip3 .
quelle
transpose
macht den Trick. Ein möglicher Algorithmus ist:Beispielsweise:
Die Antwort wird auf die Größe der kürzesten Liste in der Eingabe gekürzt.
quelle
def combineLists[A](ss:List[A]*) = { val sa = ss.reverse; (sa.head.map(List(_)) /: sa.tail)(_.zip(_).map(p=>p._2 :: p._1)) }
Scala behandelt alle seine verschiedenen Tupel Größen wie verschiedene Klassen (
Tuple1
,Tuple2
,Tuple3
,Tuple4
, ...,Tuple22
) , während sie tun alles erben von derProduct
Merkmal, das Merkmal tragen nicht genügend Informationen , um tatsächlich die Datenwerte aus den verschiedenen Größen von Tupeln verwenden wenn sie alle von derselben Funktion zurückgegeben werden könnten. (Und Scalas Generika sind auch nicht leistungsfähig genug, um diesen Fall zu behandeln.)Am besten schreiben Sie Überladungen der Zip-Funktion für alle 22 Tupelgrößen. Ein Codegenerator würde Ihnen wahrscheinlich dabei helfen.
quelle
Wenn Sie nicht den Weg des anwendbaren Scalaz / Katzen / (fügen Sie hier Ihre bevorzugte funktionale Bibliothek ein) gehen möchten, ist der Mustervergleich der richtige Weg, obwohl die
(_, _)
Syntax beim Verschachteln etwas umständlich ist. Ändern wir ihn also:Das
&
ist hier eine willkürliche Wahl, alles was gut aussieht, sollte es tun. Bei der Codeüberprüfung werden Sie wahrscheinlich ein paar hochgezogene Augenbrauen bekommen.Es sollte auch mit allem funktionieren, was Sie können
zip
(z. B.Future
s)quelle
Ich glaube nicht, dass das möglich ist, ohne sich zu wiederholen. Aus einem einfachen Grund: Sie können den Rückgabetyp der gewünschten Funktion nicht definieren.
Wenn Ihre Eingabe beispielsweise wäre, wäre
List(List(1,2), List(3,4))
der RückgabetypList[Tuple2[Int]]
. Wenn es drei Elemente hätte, wäre der RückgabetypList[Tuple3[Int]]
und so weiter.Sie könnten zurückkehren
List[AnyRef]
oder sogarList[Product]
eine Reihe von Fällen erstellen, einen für jede Bedingung.Was die allgemeine Listentransposition betrifft, funktioniert dies:
quelle
c
im Einklang mita
oder mitb
? Und wie würden Sie es im Einklang mit dem anderen darstellen?c
stimmt es mita
(dh mit dem Index überein)?Produktkollektionen haben einen
flatZip
Betrieb bis zur Arität 22.quelle
Mit Scalaz:
Für mehr als 5:
quelle