Eindimensionales Array in mehrdimensionales

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Eindimensionales Array in mehrdimensionales

    Hi.
    Ich bekomme gerade einen riesen Knoten im Kopf.

    Ich habe ein Array mit mehreren Werten. Einer dieser Werte ist eine Teilenummer, ein anderer eine Referenznummer, die sich auf die Teilenummer bezieht.
    Nun will ich aus diesem Haufen ein mehrdimensionales Array basteln, wobei die Werte anhand der Referenznummer immer der entsprechenden Teilenummer "untergeordnet" werden sollen. Also eine hierarchische Darstellung.

    Hier ein Beispielarray:
    PHP-Code:
    Array
    (
        [
    0] => Array
            (
                [
    id] => 1
                
    [teilenr] => 10
                
    [referenz] => 0
            
    )
        [
    1] => Array
            (
                [
    id] => 5
                
    [teilenr] => 25
                
    [referenz] => 10
            
    )
        [
    2] => Array
            (
                [
    id] => 3
                
    [teilenr] => 30
                
    [referenz] => 20
            
    )
        [
    3] => Array
            (
                [
    id] => 4
                
    [teilenr] => 40
                
    [referenz] => 0
            
    )
        [
    4] => Array
            (
                [
    id] => 2
                
    [teilenr] => 20
                
    [referenz] => 10
            
    )


    Das Array sollte dann so aussehen:
    PHP-Code:
    Array
    (
        [
    0] => Array
            (
                [
    id] => 1
                
    [teilenr] => 10
                
    [referenz] => 0
                
    [unter] => Array
                    (
                        [
    1] => Array
                            (
                                [
    id] => 5
                                
    [teilenr] => 25
                                
    [referenz] => 10
                            
    )
                        [
    4] => Array
                            (
                                [
    id] => 2
                                
    [teilenr] => 20
                                
    [referenz] => 10
                                
    [unter] => Array
                                    (
                                        [
    2] => Array
                                            (
                                                [
    id] => 3
                                                
    [teilenr] => 30
                                                
    [referenz] => 20
                                            
    )
                                    )
                            )
                    )
            )
        [
    3] => Array
            (
                [
    id] => 4
                
    [teilenr] => 40
                
    [referenz] => 0
            
    )


    Wie gesagt, da bekomme ich einen Knoten im Kopf. Nach was müsste ich suchen, um so etwas umzusetzen? Eine Überlegung war, eine Funktion zu schreiben und diese dann per array_walk auf das Array anzuwenden, allerdings stecke ich dann schon wieder bei der Funktion fest.

    Vielleicht ist ja jemand so nett und hilft mir auf die Sprünge oder kann sogar ein Codebeispiel liefern.


    Danke im Voraus

  • #2
    Verstehe nicht was du damit bezweckst !?
    "Nicht jeder Mensch kann und soll Programmieren[...]".

    Kommentar


    • #3
      Ich würde den Hintergrund auch gern erfahren. Vielleicht läßt sich das ganze Problem auch umschiffen. Oder zumindest die Struktur des Zielarrays vereinfachen ...

      Zur Sache: Sortiere dein Array erstmal so, dass jedes Element garantiert vor allen denen kommt, die es referenzieren. Dann iterierst du über alle Element und wenn referenz != 0 ist, dann hängst du das Element um. Dazu suchst du rekursiv nach dem Element mit id == referenz und ... der Rest ist klar.

      Kommentar


      • #4
        Ok, ein bisschen Hintergrund.
        Ich erhalte eine Excel-Datei mit mehreren hundert oder tausend Einträgen. Diese importiere ich in eine MySQL-Datenbank (wofür ich noch eine Art 'Importer' schreiben wollte später).

        Diese Excel-Datei ist folgendermaßen aufgebaut: Teilenummer, Name, [...], Referenz auf eine Teilenummer.

        Die Datei beschreibt einzelne "Baugruppen", die sich aus verschiedenen Teilen zusammensetzen.
        Also z.B.
        Baugruppe 1 [Teilenummer 0001] [Referenz irgendwas, taucht nicht in den Teilenummern auf]
        Diese besteht aus:
        - Teil ABC [Teilenummer 00023] [Referenz 0001]
        - Teil XYZ [Teilenummer 00051] [Referenz 0001]

        Teil XYZ kann nun aber wieder eine Baugruppe sein (muss aber nicht), also wieder aus mehreren Teilen bestehen.
        Also:
        - Teil XXX [Teilenummer 34123] [Referenz 00051]
        - Teil YYY [Teilenummer 34124] [Referenz 00051]

        Und so weiter. Der bisherige Ausschnitt aus der Excel-Datei, die ich erhalten habe, hat 8 Hierarchiestufen. Das können aber durchaus mehrere sein.
        Also ein "klassisches" mehrdimensionales Array in Excel Form (ohne Einrückungen natürlich in der Datei):
        Code:
        - Teil ABC
        - Teil XYZ
        	- Teil XXX
        		- Teil XXX1
        		- Teil XXX2
        			- Teil XXX21
        		- Teil XXX3
        	- Teil YYY
        - Teil EFG

        Ich suche jetzt praktisch eine Möglichkeit, wie ich diesen Datensatz anhand der einzelnen Hierarchiestufen darstellen kann.
        In der fertigen Darstellung sollte eine Liste mit allen Baugruppen der Stufe 1 angezeigt werden. Bei einem Klick auf diese soll dann aufgeklappt werden, und Stufe 2 zu dieser Baugruppe angezeigt werden, bis hinunter zur letzten Ebene.

        Ob ich jetzt ein Array sortiere oder gleich die Darstellung mache ist ja zweitranging, die Umformung und Zuweisung muss ja so oder so vorgenommen werden.


        Mein bisheriger Ansatz war, dass ich erstmal die Daten aus der DB auslese und komplett in ein Array packe. Danach erstelle ich ein seperates Array mit allen Teilenummern und allen Referenznummern. Dann vergleiche ich, welche Referenzen keinen Teilenummern entsprechen. Diese sind dann Hierarchie 1. Die entsprechenden Teilenummern wollte ich wiederum in ein seperates Array schreiben, und die Referenzen dieser Nummern aus dem Referenz-Array entfernen.
        Die gefunden Kompletteinträge in ein neues Array schreiben, das später das mehrdimensionale fertige Array werden soll.

        Nun - dachte ich mir zumindest - könnte man die restlichen Referenznummern mit dem seperaten Array der Teilenummern vergleichen, was Hierarchie 2 ergeben müsste. Die gefundenen Einträge wieder in das mehrdimensionale Array schreiben, und die Teilenummern in das Array schreiben, sowie die Referenznummern der Einträge aus dem Referenz-Array löschen, etc.
        Eigentlich müsste ich so den gesamten Datensatz durchgehen können. Eigentlich. Denn genau hier setzt mein Hirn bzw. mein Wissensstand aus, und der Knoten übernimmt den Platz meiner Neuronen.

        Diese Funktion zu schreiben, sofern sie überhaupt funktionert, erscheint mir momentan nicht möglich.


        Ich hoffe, das Problem ist jetzt etwas klarer.

        Kommentar


        • #5
          Warum willst du vor dem importieren so einen Baum bauen? Importiert werden die Daten doch sowieso wieder plain.
          Die Regeln | rtfm | register_globals | strings | SQL-Injections | [COLOR=silver][[/COLOR][COLOR=royalblue]–[/COLOR][COLOR=silver]][/COLOR]

          Kommentar


          • #6
            Original geschrieben von tontechniker
            Warum willst du vor dem importieren so einen Baum bauen? Importiert werden die Daten doch sowieso wieder plain.
            Will ich doch gar nicht.
            [...]

            Also ein "klassisches" mehrdimensionales Array in Excel Form (ohne Einrückungen natürlich in der Datei).

            [...]

            Ich suche jetzt praktisch eine Möglichkeit, wie ich diesen Datensatz anhand der einzelnen Hierarchiestufen darstellen kann.

            [...]

            Ob ich jetzt ein Array sortiere oder gleich die Darstellung mache ist ja zweitranging, die Umformung und Zuweisung muss ja so oder so vorgenommen werden.
            Zuletzt geändert von sp00n; 17.10.2007, 13:49.

            Kommentar


            • #7
              Original geschrieben von sp00n

              Ich suche jetzt praktisch eine Möglichkeit, wie ich diesen Datensatz anhand der einzelnen Hierarchiestufen darstellen kann.
              In der fertigen Darstellung sollte eine Liste mit allen Baugruppen der Stufe 1 angezeigt werden. Bei einem Klick auf diese soll dann aufgeklappt werden, und Stufe 2 zu dieser Baugruppe angezeigt werden, bis hinunter zur letzten Ebene.

              Ob ich jetzt ein Array sortiere oder gleich die Darstellung mache ist ja zweitranging, die Umformung und Zuweisung muss ja so oder so vorgenommen werden.


              Mein bisheriger Ansatz war, dass ich erstmal die Daten aus der DB auslese und komplett in ein Array packe. Danach erstelle ich ein seperates Array mit allen Teilenummern und allen Referenznummern. Dann vergleiche ich, welche Referenzen keinen Teilenummern entsprechen. Diese sind dann Hierarchie 1. Die entsprechenden Teilenummern wollte ich wiederum in ein seperates Array schreiben, und die Referenzen dieser Nummern aus dem Referenz-Array entfernen.
              Die gefunden Kompletteinträge in ein neues Array schreiben, das später das mehrdimensionale fertige Array werden soll.

              [...]

              Ich hoffe, das Problem ist jetzt etwas klarer. [/B]
              Hallo hallöchen, dieser Thread kommt ja wie gerufen.
              Ich sitze gerade an einem Problem mit einer ganz ähnlichen Basis. Ich habe hier eine Menü-Tabelle, in der jeder Eintrag die attribute "parent" und "is sub" kennt.... ohne Umschweife, das Array:
              Code:
              Array
              (
                  [Kontakt] => Array
                      (
                          [id] => 4
                          [func] => static_page
                          [custom] => 4
                          [sub] => 
                          [parent] => 
                          [order] => 1
                          [title] => Kontakt
                      )
              
                  [NWS] => Array
                      (
                          [id] => 1
                          [func] => static_page
                          [custom] => 1
                          [sub] => 1
                          [parent] => 
                          [order] => 2
                          [title] => NWS
                      )
              
                  [Service] => Array
                      (
                          [id] => 2
                          [func] => show_newsindex
                          [custom] => 
                          [sub] =>
                          [parent] => 1
                          [order] => 3
                          [title] => Service
                      )
              erhalte ich ungefähr so aus der DB. Service ist also ein Untermenü von NWS.
              Zudem Speichere ich das gleiche Array nochmal mit der ID als Schlüssel!

              Ich habe bisher den Ansatz verfolgt, mir beim auslesen der DB ein drittes Array zu basteln, welches als Schlüssel eine ID und als Werte die Untermenüs enthält, was in diesem Falle so aussieht:
              Code:
              Array
              (
                  [1] => Array
                      (
                          [0] => Service
                      )
              Mein PHP Code dazu sieht so aus:
              PHP-Code:
              <?
              $res = mysql_co("SELECT * FROM `mydb`.`menu` ORDER BY `mparent`, `morder` ASC LIMIT 0 , 330");
              $mark = 0;

              while ($menu = mysql_fetch_array($res)) {
                  $_menu[$menu['mtitel']] = $_menu_id[$menu['mid']] = array (

                      "id" => $menu['mid'],            "func" => $menu['mfunc'],            "custom" => $menu['mcustom'],

                      "sub" => $menu['msub'],        "parent" => $menu['mparent'],        "order" => $menu['morder'],        "title" => $menu['mtitel']

                  );


                  if ($menu['mparent']) { // ist KEIN ROOT entry
                      if ($mark != $menu['mparent']) { $mark = $menu['mparent']; unset($_submen); }
                      $_submen[] = $menu['mtitel'];
                      $_submenu[$menu['mparent']] = $_submen;
                  }
              }
              mysql_free_result($res);

              ?><pre><? # Debug:

              print_r($_menu);
              print_r($_menu_id);
              print_r($_submenu);
              ?></pre>
              Problem ist jetzt nur, wie man dieses Arrays nun auch Rekursiv darstellt..

              Ich hatte da ca. sowas:
              PHP-Code:
              <?
              function pr_menu($_menu, $_submenu, $current) {

                  $submenu_ids = array();

                  foreach ($_menu as $key => $i) {

                      if (empty($i['parent'])): // menu entry is in root
                          echo ' <a href="?mid=' . $i['id'] . '" class="menu">' . htmlentities($key, ENT_QUOTES) . "</a><br />\n";

                          if ($_menu[$i['title']]['sub'] == 1) { // has sub-entries, print em:
                              $submenu_ids[] = $i['title'];
                          }
                      endif;
                  }
                  return $submenu_ids;
              }                

              function print_submenu($m) {

                  global $_menu_id;

                  if ($m['sub'] === "1") {
                      if ($m['parent'] >= 1) { pr_submenu($m['parent']); echo '<div class="submenu">'; pr_submenu($m['id']); echo "</div>"; }
                      else pr_submenu($m['id']); 
                  }
                  elseif ($m['parent'] >= 1) {
                      if ($_menu_id[$m['parent']]['parent'] >= 1) { pr_submenu($_menu_id[$m['parent']]['parent']); echo '<div class="submenu">'; }
                      pr_submenu($m['parent']);
                      if ($_menu_id[$m['parent']]['parent'] >= 1) echo "</div>";
                  }
              }


              function pr_submenu($id) { 

                  global $_submenu, $_menu;
                  $result = array();

                  echo '<div class="submenu">';
                  foreach ($_submenu[$id] as $i => $b) { 
                      echo '<a href="?mid=' . $_menu[$b]['id'] .'" class="menu submenu">' . htmlentities($b, ENT_QUOTES) . "</a> <br />\n"; 
                      if ($_menu[$b]['sub'] == 1) $result[] = $_menu[$b]['title'];
                  }
                  echo "</div>\n";
                  return $result;
              }





              $userwants = false;

              if (!empty($_GET['mid'])) {

                  // $m is set here:

                  if (is_numeric($_GET['mid'])     && isset($_menu_id[$_GET['mid']]) && is_array($m = $_menu_id[$_GET['mid']])) {

                      // if input is a number and a valid menu-array, then store it

                      $userwants = $_GET['mid']; // nicht weiter von belang hier

                      $cat = $_menu_id[$_GET['mid']]['title']; // das auch nicht
                      } else $userwants = -1; // default 404

              }

              // Letztendlich:

              /*** PRINT MENU ***/
              $subs = pr_menu($_menu, $_submenu, $userwants);
              /*** if submenus, print ***/
              if (isset($m)):    
                  print_submenu($m);
                  // do whatever now
                     // ...
              endif;

              ?>
              Das funktioniert soweit, aber nur mit zwei Ebenen... und sehr schön scheint mir die Lösung auch nicht.

              Need input.


              Gruß,

              c0re

              Kommentar


              • #8
                Ich verweise mal auf einen früheren Thread:
                http://php-resource.de/forum/showthr...threadid=87055
                Habe ich aber nie getestet! Aber vielleicht als Anregung

                Kommentar


                • #9
                  Ich werfe einfach mal Nested Sets in den Raum. Da kriegt man ein solch gewünschtes Array mittels einer entsprechenden SQL Query ohne grosses Zutun von PHP heraus.
                  Gutes Tutorial | PHP Manual | MySql Manual | PHP FAQ | Apache | Suchfunktion für eigene Seiten

                  [color=red]"An error does not become truth by reason of multiplied propagation, nor does truth become error because nobody sees it."[/color]
                  Mohandas Karamchand Gandhi (Mahatma Gandhi) (Source)

                  Kommentar


                  • #10
                    Aah jahlives, genial! Danke für den Link.
                    Das ist genau die Art von Lösung die ich mir erwünschte

                    Kommentar


                    • #11
                      Das ist genau die Art von Lösung die ich mir erwünschte
                      imho ist das sogar die einzigste Lösung ein solches Problem einigermassen performant umzusetzen. Der kleine Pferdefuss bei Nested Sets ist das Einfügen neuer Elemente, weil dazu u.U. die keys aller Elemente geändert werden müssen.
                      Der entscheidende Vorteil ist die unglaubliche Flexibilität v.a. in Bezug auf die beliebige Tiefe der Verschachtelung.
                      Ich verwende für Nav Menues (ab einer bestimmten Grösse) eigentlich nur noch Nested Sets (hat mir hier glaub ich wahsaga einmal um die Ohren gehauen und seitdem mache ich das so)
                      OffTopic:

                      Weiss wer wo wahsaga steckt? Schon lange nix mehr gelesen von ihm


                      Gruss

                      tobi
                      Gutes Tutorial | PHP Manual | MySql Manual | PHP FAQ | Apache | Suchfunktion für eigene Seiten

                      [color=red]"An error does not become truth by reason of multiplied propagation, nor does truth become error because nobody sees it."[/color]
                      Mohandas Karamchand Gandhi (Mahatma Gandhi) (Source)

                      Kommentar

                      Lädt...
                      X