So gruppieren Sie ähnliche Elemente in einer Liste mit Haskell?
Gegeben eine Liste von Tupeln, wie diese:
dic = [(1,"aa"),(1,"cc"),(2,"aa"),(3,"ff"),(3,"gg"),(1,"bb")]
So gruppieren Sie Elemente von dic was in einer Liste grp wo
grp = [(1,["aa","bb","cc"]), (2, ["aa"]), (3, ["ff","gg"])]
Ich bin eigentlich ein Neuling in Haskell...und scheint zu sein, fallen in der Liebe mit ihm..
Mit Gruppe oder groupBy in Daten.Liste wird die einzige Gruppe, ähnlich wie benachbarte Elemente in einer Liste.
Ich schrieb eine ineffiziente Funktion für diese, aber es führt in-memory-Fehler, wie ich brauche, um Verfahren eine sehr große codierten string-Liste. Hoffe, Sie würden mir helfen, einen effizienteren Weg.
- Sieht aus wie eine Hausaufgabe oder so etwas. Besser, fügen Sie Ihren Ansatz und bitten der community nach Möglichkeiten, es zu verbessern, statt nur zu Fragen die Antwort.
- Sorry, ich bin ein Neuling auf stackoverflow..Entschuldigung für nicht beachten von Regeln der Gemeinschaft.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist meine Lösung:
Dies funktioniert so, dass zunächst die Sortierung der Liste mit
sortBy
:dann gruppieren Sie die Liste Elemente, indem Sie auf die entsprechende Taste mit
groupBy
:und dann die Umwandlung der gruppierten Elemente Tupel mit
map
:Testen:
Wann immer möglich, die Wiederverwendung von code für die Bibliothek.
Probieren Sie es aus, im ghci:
toList . fromListWith op
Muster eine Menge, aber ich Frage mich, wie teuer die Konvertierungen in und ausMap
sind im Vergleich zu Fuß über die Liste und gruppieren Sie Sie manuell.fromListWith (flip (++))
stattfromListWith (++)
.fromListWith (++) [((), [()]) | x <- [1..10000]]
mit der Leistung derfromListWith (flip (++)) [((), [()]) | x <- [1..10000]]
. 😉 (Spoiler:(++)
ist die richtige, nichtflip (++)
.)insertWith
/insertWithKey
, die diefromListWith
- Funktion verwendet jedenfalls, zu urteilen, die Quelle.Du kannst auch TransformListComp - Erweiterung, zum Beispiel:
Wenn die Liste nicht sortiert ist, die auf das erste element, ich glaube nicht, dass Sie tun können, besser als O(nlog(n)).
Eine einfache Möglichkeit wäre, nur
sort
und dann alles verwenden, was aus der Antwort der zweite Teil.Können Sie aus
Data.Map
eine Karte wieMap k [a]
um erste element der Tupel-Taste und halten auf hinzufügen, um die Werte.Schreiben Sie Ihre eigene komplexe Funktion, die auch nach all den versuchen noch O(nlog(n)).
Wenn die Liste ist sortiert nach dem ersten element, wie der Fall in deinem Beispiel, dann ist die Aufgabe trivial, für so etwas wie groupBy-wie in der Antwort von @Mikhail oder verwenden foldr und es gibt zahlreiche andere Möglichkeiten.
Beispiel für die Verwendung von foldr ist hier: