Map mit bestimmter Schlüssel Reihenfolge



  • Hallo,

    ich speichere bestimmte Daten in einer Map<string,string>. Die Anzalh der Schlüssel und deren Namen sind bekannt.
    Diese Map wird dann per XML in eine Textdatei abgelegt, soweit kein Problem.

    Jetzt möchte ich aber, dass Elemente der Map in einer bestimmten Reihenfolge abgelegt werden (damit man die XML-Datei später besser lesen kann).

    Wie mache ich das am besten? Wenn ich die Map mit einem Iterator auslesen, bekomme ich ja die Elemente alphabetisch nach dem Schlüssel. Ich würde aber gerne die Reihenfolge selbst bestimmen.

    MfG, martl



  • Maps nehmen als zusätzlichen Template-Parameter einen Functor, der für die anordnung der Elemente in der Map sorgt. Must du IMO nur einen entsprechenden überladen und mit angeben. default ist std::less IMO



  • martl schrieb:

    Wie mache ich das am besten? Wenn ich die Map mit einem Iterator auslesen, bekomme ich ja die Elemente alphabetisch nach dem Schlüssel. Ich würde aber gerne die Reihenfolge selbst bestimmen.

    Das geht nicht, die Reihenfolge ist „by design“. Die Map verwendet intern eine Rot-schwarz-Baum-Datenstruktur, die Reihenfolge der Daten ist daher durch ihren Schlüssel festgelegt.

    Das einzige, was Du machen könntest, wäre, die Werte linear auszulesen (also als Schlüssel-Wert-Paare in einen Vektor zu kopieren) und dann nach einem von Dir gewählten Kriterium zu sortieren.

    /EDIT: Frage falsch verstanden. Darths Lösung sollte gehen.



  • Mach doch einen vector<short> , in dem die Indexe in der von dir gewünschten Reihenfolge gespeichert sind.



  • Mach doch einen

    vector<short>
    

    Aber eine Map hat doch gar keine numerischen Indizes..., oder?



  • martl schrieb:

    Mach doch einen

    vector<short>
    

    Aber eine Map hat doch gar keine numerischen Indizes..., oder?

    Doch das ist ja gerade der Clue an std::vector.

    std:vector<int> a;
    
    for (int i = 0; i < 100; i++)
        std::cout << a[i];
    


  • martl schrieb:

    Mach doch einen

    vector<short>
    

    Aber eine Map hat doch gar keine numerischen Indizes..., oder?

    drakon schrieb:

    Doch das ist ja gerade der Clue an std::vector.

    @ Drakon: Ich glaube, er meinte Map und nicht Vektor 😉

    Ich kenne mich selber nicht gut mit Maps aus; aber auch wenn du mit Indizes nicht direkt arbeiten kannst, kannst du ja mit Iteratoren die einzelnen Elemente durchgehen, und somit auch auf das Element an einer bestimmten Stelle zugreifen.



  • Nexus schrieb:

    martl schrieb:

    Mach doch einen

    vector<short>
    

    Aber eine Map hat doch gar keine numerischen Indizes..., oder?

    drakon schrieb:

    Doch das ist ja gerade der Clue an std::vector.

    @ Drakon: Ich glaube, er meinte Map und nicht Vektor 😉

    Also wenn ich sein Quote anschaue und das was er schreibt, bin ich davon ausgegangen, dass er vector gemeint hat.
    Es geht ja _gerade darum_, dass map keine Indices hat. (Zumindest nicht, wenn man es nicht selber macht, was ich aber schwachsinnig finden würde, weil es ja genau dafür std::vector gibt.. )



  • Also noch mal zur Klarstellung. Ich habe ein Map mit jeweils zwei Strings. Der Inhalt des ersten Strings wird in einer Datei durch den zweiten String ersetzt.

    Wenn ich jetzt also noch die Reihenfolge dazu brauche, dann soll ich also jeweils den ersten String jedes Elements der Map in einen Vector schreiben und zwar in der richtigen Reihenfolge. Dann könnte ich folgendes machen:

    vector<string> keys;
    map<string,string> data;
    
    // hier die initialisierung von keys und data
    
    for(vector<string>::iterator iter = keys.begin(); iter != keys.end(); ++iter)
    {
        cout << data[*iter] << endl;
    }
    

    Und hätte damit die Elemente der Map in der Reihenfolge in der sie der Vektor vorgibt.

    Hat jemand noch einen besseren Vorschlag?



  • Du kannst sort benutzen.

    http://www.cppreference.com/cppalgorithm/sort.html

    Da kannst du (mit dem letzten Argument) eine eigene Bedingung für die Sortierung angeben.


Log in to reply