Enrico: Assoziatives Array einem übergeordneten Array zuordnen

Hallo,

ich habe eine Frage zur Umstellung einer reinen Javascript-Struktur nach folgendem Muster:

var Film = new Array ();
   Film[0]          = new object ();
   Film[0]["Nr"]    = "...";
   Film[0]["Titel"] = "...";

Ich möchte nun jeweils 30 Filme einem Array "Seite" zuordnen, um die Bildschirmausgabe zu
beschleunigen, indem ich bei der Ausgabe nicht mehr das komplette Array "Film", sondern
jeweils ein Array-Element "Seite" durchlaufen muss.

Folgende Zuordnungsstruktur will ich erreichen:

Seite[0]Film[0]["Nr"]
   Seite[0]Film[0]["Titel"]
        ...usw...
   Seite[0]Film[1]["Nr"]
   Seite[0]Film[1]["Titel"]
        ...usw...
   Seite[0]Film[29]["Nr"]
   Seite[0]Film[29]["Titel"]

Seite[1]Film[30]["Nr"]
   Seite[1]Film[30]["Titel"]
        ...usw...
   Seite[1]Film[31]["Nr"]
   Seite[1]Film[31]["Titel"]
        ...usw...
   Seite[1]Film[39]["Nr"]
   Seite[1]Film[39]["Titel"]

Wie kann ich das ohne JSON umsetzen?

Ohne JSON deshalb, weil ich meine Textdatenbank in einem versteckten Frame anzeigen lasse,
den Inhalt in eine Variable einlese und daraus dann mein Array erzeuge.

Dies will ich beibehalten.

Vielen lieben Dank für Eure Mithilfe.

Gruß
Enrico

  1. Hmm, was ist deine Frage?

    Du hast einen Array mit allen Film-Objekten und willst jetzt einen kleineren Array mit nur x Filmobjekten bauen. Richtig?

    Durchlaufe den Gesamt-Array und kopiere (= referenziere) je 30 Filme in ein Array-Element des Seiten-Arrays. Deine beispielhafte Struktur ist schon ganz richtig, jetzt musst du den Array nur noch anlegen und in einer Schleife befüllen.

    Wo liegt das Problem?

    Wie kann ich das ohne JSON umsetzen?

    ?? Ich wüsste nicht, wie man das *mit* JSON umsetzen könnte.

    Mathias

    1. Hallo Mathias,

      mein Problem ist, dass ich irgendwie auf dem Schlauch stehe und nicht weiß,
      wie ich diese Zuweisung umsetzen kann...

      Momentan ist meine Struktur wie folgt:

      var Rohdaten = top.window.frames[0].document.body.innerHTML;
         var Einzelne_Filme = Rohdaten.split ("\n");

      for (var i = 0; i < Einzelne_Filme.length; i++)
         {
            var Spalten = Einzelne_Filme[i].split ("|");

      Film[i] = new Object ();
            Film[i]["Nr"]  = Spalten [0];
            Film[i]["Titel"]  = Spalten [1];
            Film[i]["Inhalt"] = Spalten [2];
            Film[i]["Genre"]  = Spalten [3];
            Film[i]["FSK"] = Spalten [4];
         }

      Hier lese ich den unsichtbar angezeigten Inhalt des Frames "Rohdaten" in
      eine Variable ein und splitte die Variable, so dass ich zunächst einzelne
      Zeilen, also die einzelnen Filme, zusammen mit ihren Daten, bekomme.

      Die einzelnen Zeilen splitte ich in ihre Spalten auf und komme so an die
      einzelnen Daten der jeweiligen Filme.

      Wie muß ich meinen Ansatz umändern, um nun die Zuweisung von jeweils 30
      Filmen zu jeweils einer Seite zu bekommen?

      Vielen Dank und Gruß
      Enrico

      1. Wie muß ich meinen Ansatz umändern, um nun die Zuweisung von jeweils 30
        Filmen zu jeweils einer Seite zu bekommen?

        Den Ansatz behalten. »Deine beispielhafte Struktur ist schon ganz richtig, jetzt musst du den Array nur noch anlegen und in einer Schleife befüllen.«

        Den Array mit allen Filmen würde ich nicht »Film« nennen, sondern »Filme«. Dann kannst du ein einzelnes Filmobjekt »Film« nennen.

        »Durchlaufe den Gesamt-Array und kopiere (= referenziere) je 30 Filme in ein Array-Element des Seiten-Arrays. «

        var filmeNachSeiten = [];
        for (var i = 0, film; film = filme[i]; i++) {
           // Zahl durch 30 ohne Rest teilbar? Das ist bei 0 der Fall, bei 30, bei 60, bei 90 usw.
           if (i % 30) {
             // wenn ja, erzeuge neuen Seiten-Array
             var seite = [];
             // Und speichere Seiten-Array im filmeNachSeiten-Array
             filmeNachSeiten.push(seite);
           }
           // Speichere Film im Seiten-Array
           seite.push(film);
        }

        Weiß nicht, ob das klappt, aber so in etwa wäre der Ansatz.

        Ein anderer:

        for (var i = 0; i < filme.length; i += 30) {
           seite.push( film.slice(i, i + 30) );
        }

        Mathias

        1. Sorry, Mathias, versteh nur Bahnhof... :-(

          Gruß Enrico

          1. Ich habe es jetzt folgendermaßen vorgesehen:

            var Rohdaten = top.window.frames[0].document.body.innerHTML;
                  var Einzelne_Filme = Rohdaten.split ("\n");

            var Seite = new Array ();
                  var Index = 1;

            for (var i = 0; i < Einzelne_Filme.length; i++)
                  {
                     var Spalten = Einzelne_Filme[i].split ("|");

            if (i % 30)
                     {
                        Index += 1;
                     }

            Seite [Index] = new array ();
                     Seite [Index][i] = new object ();
                     Seite [Index][i]["Nr"]     = Spalten [0];
                     Seite [Index][i]["Titel"]  = Spalten [1];
                     Seite [Index][i]["Inhalt"] = Spalten [2];
                     Seite [Index][i]["Genre"]  = Spalten [3];
                     Seite [Index][i]["FSK"]    = Spalten [4];
                  }

            Hier bekomme ich die Fehlermeldung:

            Fehler: array is not defined

            Angenommen, ich würde dieses Konstrukt irgendwann zum Laufen bringen, dann
            hätte ich auch schon das nächste Problem, wie ich dann meine Sortierfunktion
            umstellen und an die neue Struktur anpassen müsste.

            Bislang sortiere ich einfach über folgende (beispielhafte) Anweisung:

            Film.sort (DVD_Nr_1);

            function DVD_Nr_1 (a, b)
               {
                  var x = a.Nr;
                  var y = b.Nr;

            return x - y;
               }

            Dies müsste dann ja auch (erheblich ?) ausgeweitet werden?!

            Gruß
            Enrico

            1. Seite [Index] = new array ();
                       Seite [Index][i] = new object ();

              Die Konstruktorfunktionen heißen Array und Object.
              Groß- und Kleinschreibung macht in JavaScript einen Unterschied.

              Bislang sortiere ich einfach über folgende (beispielhafte) Anweisung:
              Dies müsste dann ja auch (erheblich ?) ausgeweitet werden?!

              Das Aufteilen in Seiten kannst du nach nach der Sortierung immer wieder durchführen, der Seiten-Array wird einfach geleert und neu befüllt.
              (Deshalb solltest du Einlesen der Textdatei und Aufteilung nach Seiten nicht unbedingt an derselben Stelle lösen, sondern es auslagern, wie meine beiden Beispiele zeigten.)

              Mathias

              1. Hallo Mathias,

                mit nachfolgenden Konstruktionen klappt es, ich bekomme zumindest keine Fehlermeldung und die Seitenanzahlen werden korrekt erzeugt:

                function Datenbank_aufbauen ()
                   {
                      var Rohdaten = top.window.frames[0].document.body.innerHTML;
                      var Einzelne_Filme = Rohdaten.split ("\n");

                for (var i = 0; i < Einzelne_Filme.length; i++)
                      {
                         var Spalte = Einzelne_Filme[i].split ("|");

                Filme[i] = new Array ();
                         Filme[i]["Nr"]     = Spalte [0];
                         Filme[i]["Titel"]  = Spalte [1];
                         Filme[i]["Inhalt"] = Spalte [2];
                         Filme[i]["Genre"]  = Spalte [3];
                         Filme[i]["FSK"]    = Spalte [4];
                      }

                Filme_in_Seiten_organisieren ();
                   }

                function Filme_in_Seiten_organisieren ()
                   {
                      var Seitenzahl = 1;
                      Seite [1]      = new Array ();

                for (var i = 0; i < Filme.length; i++)
                      {
                         if (i % 30 == 0)
                         {
                            Seitenzahl         = Seitenzahl + 1;
                            Seite [Seitenzahl] = new Array ();
                         }

                Seite [Seitenzahl].push (Filme [i]);
                      }
                   }

                Nur:

                Wie greife ich nun auf die Elemente des Arrays "Seite" zu ?

                Über die nachfolgende (testweise) Anweisung klappt es nicht:

                alert (Seite[1]Film[0]["Titel"]);

                Hier bekomme ich folgende Fehlermeldung:

                Fehler: missing ) after argument list

                Wie muß ich den Zugriff richtig definieren ?

                Vielen Dank und Gruß
                Enrico

                1. mit nachfolgenden Konstruktionen klappt es, ich bekomme zumindest keine Fehlermeldung und die Seitenanzahlen werden korrekt erzeugt:

                  Schade, dass du dir nicht angeschaut hast was ich gemacht hatte. Dann könntest du sehen wie es einfacher, effizienter und vor allem erweiterbar geht.

                  aber um deine Frage zu beantworten:
                  alert (Seite[1][0].Titel);

                  Struppi.

                  1. Hallo Struppi,

                    ooooooooooh, wirklich riesen Sorry, hab ich übersehen/überlesen... :-(

                    Ein sehr guter Ansatz, ganz toll, werde ich mir gleich mal genauer zu
                    Gemüte führen :-)

                    Danke für Deine Bemühungen.

                    Gruß
                    Enrico

                    1. Hallo Struppi,

                      ich habe mich jetzt zur Umsetzung eines anderen Ansatzes entschieden.

                      Ich werde jetzt nicht mehr die Filme einem übergeordneten Array "Seite" zuweisen,
                      sondern will jetzt die Seitenerzeugung bzw. die "Zuordnung" der einzelnen Filme
                      zu einer bestimmten "Seite" direkt bei der Erzeugung der Tabelle selbst vornehmen:

                      function Tabelle_aufbauen ()
                         {
                            var Tabelle = "<table><thead><tr><th>Nr.</th><th>Cover</th><th>Titel</th><th>Inhalt</th><th>Genre</th><th>FSK</th></tr></thead>";

                      for (var i = 0; i < Filme.length; i++)
                            {
                               if (i % 30 == 0)
                               {
                                  Tabelle += '<tbody id="' + Anzahl_Seiten + '">';
                               }

                      Tabelle += '<tr>';

                      if (Filme[i]["Nr"].substring(0,1) == "*")
                               {
                                  var Zelle = '<td><font class="gruen">' + Filme[i]["Nr"].substring(1) + '</font></td>';
                               }
                               else
                               {
                                  var Zelle = '<td>' + Filme[i]["Nr"] + '</td>';
                               }

                      Tabelle += '<td>' + Filme[i]["Nr"] + '</td>';
                               Tabelle += '<td><img src="GRAFIKEN/COVER/' + Filme[i]["Titel"] + '.png" width="70" height="102"></td>';
                               Tabelle += '<td nowrap>' + Filme[i]["Titel"] + '</td>';
                               Tabelle += '<td width="100%">' + Filme[i]["Inhalt"] + '</td>';
                               Tabelle += '<td nowrap>' + Filme[i]["Genre"] + '</td>';
                               Tabelle += '<td><img src="GRAFIKEN/LAYOUT/FSK_' + Filme[i]["FSK"] + '.png"></td>';
                               Tabelle += '</tr>';

                      if (i % 30 == 0)
                               {
                                  Tabelle += "</tbody>";
                                  Anzahl_Seiten += 1;
                               }
                            }

                      Tabelle += "</table>";

                      var Anzeigebereich = document.getElementById ("Anzeigebereich");
                            Anzeigebereich.innerHTML = Tabelle;

                      var Hoehe_div_komplett = document.defaultView.getComputedStyle(Anzeigebereich, "").getPropertyValue("height");
                            Hoehe_div = Hoehe_div_komplett.split('px');
                            Hoehe_div = Hoehe_div[0];

                      var Hoehe_Seite = Anzeigebereich.scrollHeight;

                      if (Hoehe_Seite > Hoehe_div)
                            {
                               Anzeigebereich.className = "Zusaetzlicher_Abstand";
                            }

                      if (Initialisierung == true)
                            {
                               Initialisierung = false;
                            }

                      Seite_anzeigen (1);
                         }

                      Die Funktion "Seite_anzeigen" sollte eigentlich nun alle "tbodies" ausblenden, deren ID nicht der Seitennummer entsprechen:

                      function Seite_anzeigen (Seitennummer)
                         {
                            for (var i = 1; i <= Anzahl_Seiten; i++)
                            {
                               var Seitengruppe = document.getElementById (i);

                      if (i == Seitennummer)
                               {
                                  Seitengruppe.style.display = "";
                               }
                               else
                               {
                                  Seitengruppe.style.display = "none";
                               }
                            }
                         }

                      Hier bekomme ich aber in der Fehlerkonsole von Firefox folgende Fehlermeldung:

                      Fehler: Seitengruppe is null

                      Ich kann mir diesen Fehler nicht erklären, da ich jedem tbody eine eigene, eindeutige ID zuweise, so dass hier keine Doppel-IDs
                      vorkommen.

                      Kannst Du mir hier bitte weiterhelfen?

                      Gruß
                      Enrico

                      1. Hi,

                        Ich kann mir diesen Fehler nicht erklären, da ich jedem tbody eine eigene, eindeutige ID zuweise, so dass hier keine Doppel-IDs
                        vorkommen.

                        IDs duerfen aber nicht mit einer Ziffer beginnen, geschweige denn nur aus Ziffern bestehen.

                        MfG ChrisB

                        --
                        „This is the author's opinion, not necessarily that of Starbucks.“
                        1. Hallo ChrisB,

                          ich habe jetzt die Bezeichnungen meiner "tbodies" umgestellt, so dass sie jetzt nicht mehr
                          nur numerische IDs haben, sondern IDs namens "Seite_1", "Seite_2",...

                          Da mein Code dann immer noch nicht klappte (das tut er aktuell leider immer noch), habe ich
                          gegoogelt nach "document.getElementById" und bin auf folgende Seite gestossen, die mit DIVs
                          bei den Demonstrationen arbeitet:

                          http://getelementbyid.com/scripts/search.aspx?k=getElementById&CodeID=5

                          Daraufhin habe ich meinen Code folgendermaßen umgestellt:

                          function Seite_anzeigen (Seitennummer)
                             {
                                for (var i = 1; i <= Anzahl_Seiten; i++)
                                {
                                   Tabellenbloecke = document.getElementsByTagName ("tbody");

                          var Objekt = "Seite_" + i;

                          if (i == Seitennummer)
                                   {
                                      Tabellenbloecke[Objekt].style.display = "";
                                   }
                                   else
                                   {
                                      Tabellenbloecke[Objekt].style.display = "none";
                                   }
                                }
                             }

                          Allerdings bzw. in Deinen Augen wohl erwarteterweise wieder mit der Fehlermeldung:

                          Fehler: Tabellenbloecke[Objekt] is undefined

                          Die einzelnen Gruppen ("tbodies") werden aber korrekt erzeugt. Diese Bestätigung
                          bekomme ich über einen alert-Befehl: "alert (Objekt)" innerhalb der Schleife.

                          Gruß
                          Enrico

                          1. Nochmals Hallo ChrisB,

                            ich habe jetzt meine Funktion umgestellt und greife nun anders auf die tbody-tags zu:

                            function Seite_anzeigen (Seitennummer)
                               {
                                  for (var i = 1; i <= Anzahl_Seiten; i++)
                                  {
                                     var Interner_tbody_Index = i - 1;

                            Tabellenblock = document.getElementsByTagName("tbody")[Interner_tbody_Index];

                            if (i == Seitennummer)
                                     {
                                        Tabellenblock.style.display = "";
                                     }
                                     else
                                     {
                                        Tabellenblock.style.display = "none";
                                     }
                                  }
                               }

                            Jetzt bekomme ich zwar keine Fehlermeldung mehr, die tbody-Gruppen, die nicht der
                            Seitennummer entsprechen, werden aber auch nicht ausgeblendet.

                            Somit hänge ich jetzt - vermutlich - nur noch am Wechsel der (Un-)Sichtbarkeit.

                            Gruß
                            Enrico

                            1. Hallo,

                              auch folgendes Konstrukt blendet mir keine Blöcke aus der Tabelle aus:

                              function Seite_anzeigen (Seitennummer)
                                 {
                                    for (var i = 0; i < Anzahl_Seiten; i++)
                                    {
                                       var Objekt = document.getElementById("Seite_" + i);
                                       var Objekt_ID = Objekt.id;

                              if (Objekt_ID.indexOf(Seitennummer, 6))
                                       {
                                          Objekt.style.display = "";
                                       }
                                       else
                                       {
                                          Objekt.style.display = "none";
                                       }
                                    }
                                 }

                              Natürlich habe ich zuvor die einzelnen tbody-Blöcken mit einer eindeutige ID versehen:

                              if (i % 30 == 0)
                                 {
                                    Tabelle += '<tbody id="Seite_' + Anzahl_Seiten + '">';
                                    Anzahl_Seiten += 1;
                                 }

                              Ich komm nicht dahinter, warum das nicht klappt...

                              Gruß
                              Enrico

                              1. Hi,

                                auch folgendes Konstrukt blendet mir keine Blöcke aus der Tabelle aus:

                                Fehlermeldungen?
                                Ablauf der Funktion durch eingebaute alert-Ausgaben o.ae. kontrolliert?

                                Natürlich habe ich zuvor die einzelnen tbody-Blöcken mit einer eindeutige ID versehen:

                                Hast du, bspw. im FireBug, das erzeugte DOM kontrolliert, entspricht es deinen Erwartungen?

                                MfG ChrisB

                                --
                                „This is the author's opinion, not necessarily that of Starbucks.“
                                1. Hallo ChrisB,

                                  nach folgendem Umbau der Funktion...

                                  function Tabelle_aufbauen ()
                                     {
                                        var Tabelle = "<table><thead><tr><th>Nr.</th><th>Cover</th><th>Titel</th><th>Inhalt</th><th>Genre</th><th>FSK</th></tr></thead>";

                                  var Zaehler = 0;

                                  for (var i = 0; i < Filme.length; i++)
                                        {
                                           if (Zaehler == 0)
                                           {
                                              Tabelle += '<tbody id="Seite_' + Anzahl_Seiten + '">';
                                              Anzahl_Seiten += 1;
                                           }

                                  Tabelle += "<tr>";

                                  if (Filme[i]["Nr"].substring(0,1) == "*")
                                           {
                                              var Zelle = '<td><font class="gruen">' + Filme[i]["Nr"].substring(1) + '</font></td>';
                                           }
                                           else
                                           {
                                              var Zelle = '<td>' + Filme[i]["Nr"] + '</td>';
                                           }

                                  Tabelle += Zelle;
                                           Tabelle += '<td><img src="GRAFIKEN/COVER/' + Filme[i]["Titel"] + '.png" width="70" height="102"></td>';
                                           Tabelle += '<td nowrap>' + Filme[i]["Titel"] + '</td>';
                                           Tabelle += '<td width="100%">' + Filme[i]["Inhalt"] + '</td>';
                                           Tabelle += '<td nowrap>' + Filme[i]["Genre"] + '</td>';
                                           Tabelle += '<td><img src="GRAFIKEN/LAYOUT/FSK_' + Filme[i]["FSK"] + '.png"></td>';
                                           Tabelle += '</tr>';

                                  Zaehler += 1;

                                  if (Zaehler == 30)
                                           {
                                              Tabelle += "</tbody>";
                                              Zaehler = 0;
                                           }
                                        }

                                  Tabelle += "</table>";

                                  ... zeigt mir FireBug, dass die Tabelle richtig aufgebaut wurde mit jeweils
                                  30 Filmen pro tbody, die Fehler-Konsole hingegen bringt mir folgende Meldung...

                                  Fehler: Objekt is null

                                  ...in folgender Anweisung:

                                  function Seite_anzeigen (Seitennummer)
                                     {
                                        for (var i = 0; i < Anzahl_Seiten; i++)
                                        {
                                           var Objekt = document.getElementById("Seite_" + i);
                                      ---> var Objekt_ID = Objekt.id; <---

                                  if (Objekt_ID.indexOf(Seitennummer, 6))
                                           {
                                              Objekt.style.display = "";
                                           }
                                           else
                                           {
                                              Objekt.style.display = "none";
                                           }
                                        }
                                     }

                                  In dieser Funktion habe ich versucht, die ID der einzelnen tbody-Elemente
                                  zu bekommen (als String ?) und ab der 6. Stelle auf Übereinstimmung der
                                  Ziffer mit der Seitennummer zu prüfen.

                                  Hier bekomme ich aber leider nicht mal die ID raus, so dass dann natürlich
                                  der verbleibende Block auch nie greift.

                                  Gruß
                                  Enrico

                                  1. Hallo,

                                    ich mach's jetzt ganz anders:

                                    Ich erzeuge beim Aufrufen nicht gleich die komplette Tabelle, da ich
                                    festgestellt habe, dass dies für den Browser extrem belastend ist,
                                    sondern zeige über eine Schleife nur die Filme an, die pro Seite
                                    angezeigt werden sollen (30 bzw. der verbleibende Rest bei der letzten
                                    Seite), d.h. die Tabelle wird nur für die jeweils anzuzeigenden Filme
                                    erzeugt.

                                    Ich denke, das ist der vernünftigste Ansatz (der auch klappt).

                                    Gruß
                                    Enrico

  2. Ohne JSON deshalb, weil ich meine Textdatenbank in einem versteckten Frame anzeigen lasse,
    den Inhalt in eine Variable einlese und daraus dann mein Array erzeuge.

    Probier das mal.

    Struppi.