Cleaner Tupel groupBy
Habe ich eine Folge von Schlüssel-Wert-Paare (String, Int), und ich will diese Gruppe von Schlüssel in einer Reihenfolge der Werte (D. H. Seq[(String, Int)]) => Map[String, Iterable[Int]])
).
Offensichtlich toMap
ist nicht sinnvoll hier, und groupBy
unterhält die Werte als Tupel. Die besten habe ich es geschafft zu kommen mit ist:
val seq: Seq[( String, Int )]
//...
seq.groupBy( _._1 ).mapValues( _.map( _._2 ) )
Gibt es eine bessere Möglichkeit, dies zu tun?
- +1 Verwenden Sie diese Muster so oft ich wünschte, es wurde etwas gebaut.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist ein Zuhälter, fügt eine
toMultiMap
Methode traversables. Würde es dein problem lösen?Kann z.B. so verwendet werden:
Wenn Sie fügen Sie die folgende implizite defs, es wird auch mit Inkasso-ähnliche Objekte wie
String
s undArray
s:Dann:
List(1 -> 'a', 1 -> 'à', 2 -> 'b')
, aber ich will das ErgebnistoMultiMap
zuMap[Int, Set[String]]
? Einige trick mitbreakOut
vielleicht?Gibt es keine Methode oder der Struktur der Daten in der standard-Bibliothek, dies zu tun, und deine Lösung sieht in etwa so präzise, wie Sie bekommen. Wenn Sie diese in mehr als einem Ort, möchten Sie vielleicht, um Sie Faktor in einer utility-Methode
dem Sie dann offensichtlich einfach anrufen mit
groupTuples(seq)
. Dies möglicherweise nicht die effizienteste im Hinblick auf CPU-Taktzyklen, aber ich glaube nicht, dass es besonders ineffiziente entweder.Habe ich eine grobe benchmark gegen Jean-Philippe Lösung auf eine Liste mit 9 Tupeln und dies ist geringfügig schneller. Beide waren etwa doppelt so schnell als Faltung der Sequenz in eine Karte (effektiv re-Implementierung
groupBy
zu geben, die Ausgabe, die Sie wollen).mapValues
eigentlich nur umschließt die integrierte Karte, so dass es möglicherweise weniger effizient, wenn man die Dinge in der Karte. Außerdem hab ich bearbeitet meine Antwort zu vermeidentoMap
; würden Sie mir (aus Neugier) mit dem gleichen benchmark nochmal? Mit 9 Tupeln, Bau die Karte ein und zwei lookups ist etwa ein Drittel schneller mit meinem Vorschlag nach meinen benchmarks.mapValues
einwickeln der vorhandenen Karte - ich wusste nicht, dass. Es entsteht eine völlig neue Karte mitseq groupBy (_._1) map (x => (x._1, x._2 map (_._2)))
dauert 165 ms, so dass für das erstellen einer neuen map im Speicher deiner ist schneller.Ich weiß nicht, ob Sie denken, dass es cleaner:
Ab
Scala 2.13
meisten Sammlungen sind mit der groupMap Methode, die (wie der name schon sagt) einen Gegenwert (effizienter) eingroupBy
gefolgt vonmapValues
:Diese:
group
s-Elemente, basierend auf dem ersten Teil von Tupeln (Map(2 -> List((2,c)), 1 -> List((1,a), (1,b)))
)map
s gruppierte Werte (List((1,a), (1,b))
), indem Sie Ihre zweite Tupel Teil (List(a, b)
).