Map sortieren
-
Hallo,
ich hab schon das Forum durchsucht und auch 1-2 Themen zum Sortieren von Maps gefunden, aber irgendwie ist da doch nicht das dabei was ich suche.
Folgende Situation:
Ich lege eine map an mit
map<string, c_meintyp> meinemap;Die Map wird ja nun automatisch alphabetisch sortiert nach dem string.
In c_meintyp sind verschiedene Werte gespeichert, nach denen ich auch gerne sortieren würde, allerdings muss ich den string als index behalten.Beispiel:
es gibt in c_meintyp eine eigenschaft "punkte" oder "status" mit integer bzw float Werten.
Nun möchte ich beim Durchlauf der Map gerne eine nach einer Eigenschaft sortierte Reihenfolge haben.Ich hab es mit diesem Thema versucht
http://www.c-plusplus.net/forum/viewtopic.php?t=70473Aber irgendwie wollte das nicht so recht.
Die Sortierung ist trotzdem geblieben wie vorher.Vielen Dank schon einmal für eure Hilfe.
Marius
-
Hallo,
poste mal ein bißchen Code.. Dann können wir dir weiterhelfen
Ich kann mir momentan nicht genau vorstellen was du möchtest.
-
Eine map braucht ihre iintere sortierung
-
Ein bisschen Code...
oki doki...--- SNAP --- map<string, c_team> team_list; --- SNAP --- class c_team{ public: c_team(); int reset_data(); int strategy, fairness; }
nun wird halt die map gefüllt mit Daten aus einer DB.
Als Identifikation gelten die Team-IDs als String.team_list[teamid_str].strategy = wert1_aus_db; team_list[teamid_str].fairness = wert2_aus_db;
usw.
Wenn ich nun eine Liste aller Einträge haben will mache ich:
map<string, c_team>::const_iterator beg=team_list.begin(); map<string, c_team>::const_iterator end=team_list.end(); while(beg != end) { cout << beg->first << " - " << team_list[beg->first].strategy << endl; beg++; }
(nur als Beispiel)
Nun wird sortiert nach den strings, also den Teamids.
(dass dies alphabetisch und nicht numerisch geschieht ist für mich nicht wichtig).Ich möchte nun aber die Ausgabe verschieden sortiert haben wenn das geht.
Einmal nach den strategy werten, dann vielleicht mal nach den fairness werten usw.
Ist das möglich?Danke
-
Das wird so wohl nicht funktionieren, wie Du Dir das vorstellst. Wie Helium schon sagte: Eine map ist bereits sortiert und benötig auch genau diese interne Sortierung um korrekt zu arbeiten.
Am einfachsten ist es wahrscheinlich einfach eine Kopie der map in einen vector zu ziehen und diesen dann zu sortieren.
Eine alternative wäre, nicht die echten Objekte, sondern nur Zeiger auf diese in die map zu füllen. Dafür dann aber mehrere maps mit verschiedenen Sortierkriterien anzulegen. Aber das erhöht den Verwaltungsaufwand und macht die Implementierung schwieriger.
Wenn es Performance-mäßig keine allzugroße Rolle spielt würde ich's mit Variante 1) versuchen.
MfG Jester
-
Hmmm,
es wäre wenigstens mal ein AnfangKann ich denn einfach die einzelnen Elemente in den Vektor "schieben" und diesen dann nach einem eigenen Kriterium sortieren?
Muss gestehen, dass ich oft durcheinander komme wenn es um sowas gehe,
da ich auch viel mit PHP mache und da dann wieder alles anders ist mit Arrays und Sortierung etc
-
Also, rüberkopieren in einen Vektor geht in etwa so:
typedef map<string, c_team> TeamMap; // einfachere Handhabung TeamList team_list; // ... // füllen // ... typedef vector<c_team> TeamVector; TeamVector team_output; for(TeamMap::iterator p = team_list.begin(); p!=team_list.end(); ++p) { team_output.push_back(p->second); } // CmpFairness ist ein von Dir geschriebener Vergleicher sort(team_output.begin(), team_output.end(), CmpFairness); //zum Beispiel so: bool CmpFairness(c_team const & lhs, c_team const & rhs) { return lhs.getFairness() < rhs.getFairness(); }
MfG Jester
-
Danke Dir, denke damit kann ich was anfangen
-
Hab doch noch eine Frage:
Kann man denn irgendwie in dem Vektor auch noch auf den Schlüssel
des c_team Elements zugreifen oder muss man den dann in der Klasse nochmal separat speichern wenn man ihn braucht?
-
Du musst den gesondert speichern. Entweder in einem zweiten vector oder (IMHO die bessere Variante) du speicherst die Daten gleich in einem vector<std::pair<std::string, c_team> >. Aus dem team_output.push_back(p->second); wird dann team_output.push_back(*p);