Schleifen



  • Guten Abend Community,

    ich habe mich ein wenig an einem Spiel versucht und hatte folgendes Szenario:

    class Map
    {
        public List<List<FieldObject>> FieldObjectCollections { get; private set; }
        public int Width
        {
            get { return this.FieldObjectCollections[0].Count; }
        }
        public int Height
        {
            get { return this.FieldObjectCollections.Count; }
        }
    }
    

    Die Feld Objekte besitzen XY-Koordinaten.
    Irgendwie finde ich das aber nicht wirklich schön, auch weil ich jedes Mal dieses Konstrukt habe:

    foreach(List<FieldObject> fieldObjects in map.FieldObjectCollections)
    {
        foreach(FieldObject fieldObject in fieldObjects)
        {
            fieldObject.Draw();
            /*
             * oder zwei for-Schleifen mit
             * map.FieldObjects[y][x].Draw()
             * was noch grausamer ist
            */
        }
    }
    

    Dazu kommt noch, dass man bei dieser Variante die Listen in der Liste ändern kann, also deren Referenz.
    Ich habe mir folgendes überlegt:

    class Map
    {
        public List<FieldObject> FieldObjects { get; private set; }
        public int Width
        {
            get
            {
                FieldObject tmp = this.FieldObjects.FirstOrDefault(fo => fo.Y == 1);
                return this.FieldObjects.IndexOf(tmp);
            }
        }
        public int Height
        {
            get
            {
                return this.FieldObjects.Last().Y + 1;
            }
        }
    }
    
    //...
    foreach(FieldObject fieldObject in map.FieldObjects)
    {
        fieldObject.Draw();
    }
    

    Ich frage mich hier jetzt, ob es einen Zeitunterschied gibt. Gibt es einen Fehler in dem Design, auf den ich später stoßen könnte? Was findet ihr besser?

    Mit freundlichen Grüßen,
    freaky


  • Mod

    Das ist schon im ersten Schritt ein Fehldesign. List<List<Objekt>> ist ja im wortwörtlichen Sinne eine Liste von Listen. Du behandelst sie aber wie ein 2D-Feld, noch dazu eines, dessen erste Dimension nicht 0 sein kann. Wenn du ein 2D-Feld willst, dann nimm doch auch eines. Das löst alle deine Probleme:
    -Du kannst über alle Einträge iterieren, sei es mittels Pointerarithmetik (oder vergleichbares Sprachmittel) oder einem passenden Wrapper. Jedenfalls reicht eine Schleife, wenn du unbedingt möchtest.
    -Die Größe der inneren Objekte ist garantiert.
    -Es ist wahrscheinlich merklich effizienter, besonders wenn die hier genannten Listen tatsächlich verkettete Listen darstellen (eine sehr ineffiziente Datenstruktur).

    Falls die Sprache deiner Wahl keine frei dimensionierbaren 2D-Felder unterstützt (ich nehme mal an, die innere Dimension soll flexibel sein, sonst hättest du dort gleich ein statisches Feld genommen?), dann kann man das ganz simpel durch ein 1D-Feld mit einem Wrapper drum herum abbilden. Objekt2D[x][y] = Objekt1D[x * y_höhe + y]



  • SeppJ schrieb:

    Es ist wahrscheinlich merklich effizienter, besonders wenn die hier genannten Listen tatsächlich verkettete Listen darstellen (eine sehr ineffiziente Datenstruktur).

    In C# ist List vergleichbar mit einer ArrayList aus Java oder std::vector .


  • Mod

    icarus2 schrieb:

    SeppJ schrieb:

    Es ist wahrscheinlich merklich effizienter, besonders wenn die hier genannten Listen tatsächlich verkettete Listen darstellen (eine sehr ineffiziente Datenstruktur).

    In C# ist List vergleichbar mit einer ArrayList aus Java oder std::vector .

    Ok, war mir nicht sicher, welche Sprache das ist. Dann ist es aber immer noch eine Liste von Listen im Sinne der Umgangssprache. Es ist keine "rechteckige" 2D-Struktur.
    Wenn sich jemand mit C# auskennt: Kann das dynamische 2D-Arrays? Ansonsten ist wohl ein Wrapper um eine 1D-Liste angesagt. Derzeit hat der TE ja ohnehin schon einen Wrapper um seine List<List>, da sollte es leicht sein, diesen anzupassen.



  • In C# kann man mit

    int[,] arr = new int[m,n];
    

    ein echtes 2D-Array dynamisch erzeugen. Funktioniert mit Wertetypen und Referenztypen. Es gibt auch Arrays von Arrays (wie in Java), die in C# Jagged Arrays heissen.


Anmelden zum Antworten