Benno: Blackout, Baumstruktur, Tree

Hallo, ich habe wohl im Moment einen Blackout.

Ich schaffe es nicht aus einem einfachen Mehrdimensionalen Array
eine Baumstruktur zu erzeugen.

Das Array in einfacher Form:
* der letzt Wert ist die ID des übergeordneten Elements

$ar[0] = array('titel_1','0');
$ar[1] = array('titel_2','0');
$ar[2] = array('titel_3','1');
$ar[3] = array('titel_4','0');
$ar[4] = array('titel_5','3');
$ar[5] = array('titel_6','4');

Rauskommen soll also sowas:

titel_1
   titel_3
      titel_5
   titel_2
   titel_4
      titel_6

bzw.
<ul>
 <li>Titel_1</li>
  <ul>
   <li>Titel_3</li>
     <ul><li>Titel_5</li></ul>
      <li>Titel_2</li>
      <li>Titel_4</li>
        <ul><li>Titel_6</li></ul>
   </ul>
</ul>

#######################################

Habe ein paar Versuche gemacht das array zu durchlaufen
und entsprechend des Elternelements rekursiv ein neues Array zu erzeugen, aber das scheitert wohl am falschen Ansatz.

Und zum richtigen Ansatz bräuchte ich mal einen Denkanstoss im Anfängerformat, denn meine Auffassungsgabe ist im Moment im Keller.

Hilft mir jemand auf die Sprünge?

Gruss
Benno

  1. Hallo!

    Das Array in einfacher Form:
    * der letzt Wert ist die ID des übergeordneten Elements

    $ar[0] = array('titel_1','0');
    $ar[1] = array('titel_2','0');
    $ar[2] = array('titel_3','1');
    $ar[3] = array('titel_4','0');
    $ar[4] = array('titel_5','3');
    $ar[5] = array('titel_6','4');

    Mal sehen... Ganz simpel:
    Ich wuerde erstmal ne einfache Schleife fahren die durchs array pfluegt und alle Eintraege mit '0' sucht und erstellt.

    Dann haette ich ne Funktion, die als Uebergabeparameter eine Eintragsnummer hat. Die ruft sich bei gefundenem Eintrag selbst mit seiner Nummer auf.

    Uebergeben musst du nur den zaehler des Arrays.

    Du kannst natuerlich nur die Funktion nehmen und sie als erstes mit einer 0 aufrufen.

    Reicht das?

    1. Hallo Steel,

      Mal sehen... Ganz simpel:
      Ich wuerde erstmal ne einfache Schleife fahren die durchs array pfluegt und alle Eintraege mit '0' sucht und erstellt.

      »»

      Das habe ich schon soweit versucht, zb.

      foreach($ar as $k => $w)
      {}

      Dann haette ich ne Funktion, die als Uebergabeparameter eine Eintragsnummer hat. Die ruft sich bei gefundenem Eintrag selbst mit seiner Nummer auf.

      hmmm, da versthe ich nicht was ich suchen soll, bzw. erstellen

      Uebergeben musst du nur den zaehler des Arrays.

      Hatte es mal so probiert:
      foreach($ar as $k => $w)
      {
      $x = $w[1];
      $newar[$x][$k] = $w
      }

      Aber weiter hatte mich das nicht gebracht.

      Du kannst natuerlich nur die Funktion nehmen und sie als erstes mit einer 0 aufrufen.

      und dann die Schleife in der Funktion laufen lassen, oder
      die funktion rekursiv anwenden? Aber worauf?

      Reicht das?

      Danke, aber leider: Nein.

      Ich sagte ja schon, bin im Moment vielleicht auch zu kompliziert
      am denken, bin seit 2 tagen an dem Mist dran, dachte wär in
      einer halben Stunde erledigt.

      Gruss
      Benno

      1. Yeah, Frühsport :))

        _______________

          
        $ar[0] = array('titel_1','0');  
        $ar[1] = array('titel_2','0');  
        $ar[2] = array('titel_3','1');  
        $ar[3] = array('titel_4','0');  
        $ar[4] = array('titel_5','3');  
        $ar[5] = array('titel_6','4');  
          
        for($i=0;$i<count($ar);$i++){  
         $buendel[$ar[$i][1]][$i]=$ar[$i];  
        }  
          
        function zeig_block($id){  
         global $buendel;  
         $block=$buendel[$id];  
         $i=0;  
         echo "<ul>\n";  
         while($i<count($block)){  
          $zeile=current($block);  
          echo "<li>".$zeile[0]."</li>\n";  
          if(isset($buendel[key($block)]) && key($block)>0){  
           zeig_block(key($block));  
           }  
          $i++;  
          next($block);  
         }  
         echo "</ul>\n";  
        }  
          
        zeig_block(0);  
        
        ~~~\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
          
          
        Zuerst hab ich die Arrays nach dem gesuchten Elternelement gebündelt  
        und anschließend mit der rekursiven Funktion "zeig\_block()" die Bündel abgearbeitet.  
        zeig\_block(0), weil mit 0 der Ablauf auf unterster Ebene ja angestossen werden muß.  
          
        Naja, jedenfalls: viel Spaß damit. :)
        
        1. Hallo Semaphor,

          Yeah, Frühsport :))
          Naja, jedenfalls: viel Spaß damit. :)

          SUPER, tausend Dank.
          Ich bin zwar momentan nicht mehr in der Lage das zu analysieren
          aber es funktioniert und das ist "Spitze".

          Ein glücklicher
          Benno

  2. Moin!

    Das Array in einfacher Form:
    * der letzt Wert ist die ID des übergeordneten Elements

    $ar[0] = array('titel_1','0');
    $ar[1] = array('titel_2','0');
    $ar[2] = array('titel_3','1');
    $ar[3] = array('titel_4','0');
    $ar[4] = array('titel_5','3');
    $ar[5] = array('titel_6','4');

    Rauskommen soll also sowas:

    titel_1
       titel_3
          titel_5
       titel_2
       titel_4
          titel_6

    Deine Testdaten passen nicht zu deinem gewünschten Baum. Überarbeite eines von beiden, gern auch beides.

    Und als Lösungsansatz empfiehlt es sich evtl., tatsächlich ein Baumarray zu erstellen. Wenn du zum Zeitpunkt von titel_2 weißt, dass dieser Unterelement von titel_1 ist, häng' es dort drunter ein. Dann kannst du jede Arrayebene durchlaufen und für gefundene Subelemente die Listenfunktion erneut rekursiv aufrufen. Rekursion ist sowieso das Mittel der Wahl, wenn es um Baumstrukturen geht - leider beißt sie sich etwas mit den sonst üblichen linearen und iterativen Speicherstrukturen z.B. in Datenbanken und Textdateien.

    - Sven Rautenberg

    --
    "Love your nation - respect the others."
    1. Hallo Sven,

      $ar[0] = array('titel_1','0');
      $ar[1] = array('titel_2','0');
      $ar[2] = array('titel_3','1');
      $ar[3] = array('titel_4','0');
      $ar[4] = array('titel_5','3');
      $ar[5] = array('titel_6','4');

      Rauskommen soll also sowas:

      titel_1
         titel_3
            titel_5
         titel_2
         titel_4
            titel_6

      Deine Testdaten passen nicht zu deinem gewünschten Baum. Überarbeite eines von beiden, gern auch beides.

      Na wunderbar, wohl nicht mal das kann ich mehr erkennen.
      Denn für mich siehts richtig aus.

      Und als Lösungsansatz empfiehlt es sich evtl., tatsächlich ein Baumarray zu erstellen. Wenn du zum Zeitpunkt von titel_2 weißt, dass dieser Unterelement von titel_1 ist, häng' es dort drunter ein.

      »»

      Ja aber wie darunter, endlos mehrdimensionalearrays?

      Meine aktuelle Funktion scheint schon falsch durchdacht zu sein.

      function maketree($ar,$id='0')
      {
      foreach($ar as $k => $w)
      {

      $x       = $w[0];
      $sub     = $w[1];

      //Ebene erstellen, also alles was $pos im sub hat
      if($sub == "$id"){$newar[$id][$k][] = $x;}
      else{$newar[$k][] = maketree($ar,$k);}
      }

      return $newar;
      }// end of func.

      Komme anscheinend einfach nicht mehr weiter ohne ein kleines Beispiel.

      Danke
      Benno

  3. Hi,

    $ar[0] = array('titel_1','0');
    $ar[1] = array('titel_2','0');
    $ar[2] = array('titel_3','1');
    $ar[3] = array('titel_4','0');
    $ar[4] = array('titel_5','3');
    $ar[5] = array('titel_6','4');

    Rauskommen soll also sowas:

    titel_1
       titel_3
          titel_5
       titel_2
       titel_4
          titel_6

    titel_1, titel_2, titel_4 haben dasselbe übergeordnete Element '0'.

    Dein Beispielbaum zeigt titel_1 auf oberster Ebene.
    titel_3, titel_2 und titel_4 sind alle unter titel_1, obwohl titel_3 ('1') ein anderes übergeordnetes Element als titel_2 und titel_4 (jeweils '0') hat.

    <ul>
    <li>Titel_1</li>
      <ul>
       <li>Titel_3</li>
         <ul><li>Titel_5</li></ul>
          <li>Titel_2</li>
          <li>Titel_4</li>
            <ul><li>Titel_6</li></ul>
       </ul>
    </ul>

    Hier ist jetzt titel_3 einziges Kind von titel_1, titel_2 und titel_4 sind plötzlich Kinder von titel 5?

    Wobei die HTML-Struktur so natürlich nicht richtig ist, da ul nur li als Kinder haben darf - die jeweiligen Unterlisten gehören ins li des übergeordneten Elements.

    Aus Deinen Beispielen wird also nicht deutlich, wie die auszugebende Struktur aussehen soll, da die beiden gezeigten Bäume überhaupt nicht zum Array passen.

    Wo kommt das Array her? Wie wird es erzeugt? Hast Du das selbst in der Hand? Wenn ja, muß es flach sein?
    Wenn nein, dann bau es gleich hierarchisch auf.
    Wenn flach, würde ich empfehlen, das wie folgt abzuspeichern:

    Root-Element
    Erstes Kind
    Erster Enkel
    Erster Urenkel
    Zweiter Urenkel
    Dritter Urenkel
    Zweiter Enkel
    Erster Urenkel
    Zweiter Urenkel
    Zweites Kind
    Erster Enkel

    usw.
    Also zuerst auf jeder Ebene das Element selbst, gefolgt von seinen Kindern (wobei jedem Kind erstmal dessen Kinder folgen, denen wiederum deren Kinder direkt folgen usw.)
    So existiert beim Wiederaufbauen des Baums aus dem Array beim Durchgehen von 0 bis n zu Element bereits dessen Vater, so daß das Element sofort dort angehängt werden kann.

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.