dedlfix: Array mit Nested Set Werten zu Html-Liste/Menu verarbeiten

Beitrag lesen

Tach!

Ich durchlaufe das "lückenhafte" Array und das einzige was ich hinkriege ist, dass ich eine Ebene tiefer muss wenn der left- oder der right-Wert kleiner als der right-Wert vom letzten Elter ist.

Das dürfte nur die halbe Wahrheit sein. Bei mehreren Geschwistern wäre das ja jedes Mal der Fall. Eigentlich müsstest du immer dann absteigen, wenn L+1 kleiner R bleibt. Aber dann steigst du auch bei blätterlosen Zweigen ab, nur um unverrichteter Dinge wieder hochzusteigen. Damit das keine leeren ul-Elemente hinterlässt, musst du hier einmal vorausschauen, um zu sehen, ob das nächste L kleiner als dein aktuelles R ist. Das wiederum macht sich mit einem foreach nicht besonders gut. Ein indexbasiertes for ist da flexibler.

Nach meinen Fehlversuchen muss ich mir auch eingestehen, dass ich überhaupt nicht weiß wie ich da mit einer Rekursion ansetzen muss. :/

Ein Stack geht auch. Leg mal die Tastatur beiseite und versuch mal mit Bleistift auf Papier das Problem zu lösen. Während du absteigst, musst du dir merken, wer der Elter ist. Und wenn du weiter absteigst, muss der Großelter aufgehoben und mit dem aktuellen Elter weitergemacht werden. Beim Aufsteigen müssen ein oder mehrere Eltern gestrichen werden. Da kommt der Stack ins Spiel (ein normales Array und die Funktionen []= (array_push()), end() und array_pop()).

Bei Rekursion würdest du durch ein globales Array laufen (alternativ durch ein immer wieder/weiter durchgeschleiftes) und statt Stack hättest du eine lokale Variable, die auf den Elter zeigt (oder eine Kopie enthält).

Spielen wir mal die Stack-Variante ausgehend von dem Array deines Eingangspostings durch. i = Element 0, das hat L=0 und R=3, es ist ein Elter. Das kommt auf den Stack, aber erstmal schauen, ob das L vom i+1 kleiner als unser R ist. Das ist der Fall, also gibt es mindestens einen Nachkommen, der Abstieg lohnt sich. (Wenn das L allerdings kleiner als oder gleich unserem L ist, dann hast du einen Nebenbaum - allerdings passt diese Aussage nicht mehr, wenn es Teilbäume ohne Wurzeln gibt - aber vielleicht bekommst du sowas anhand der Menü-ID oder ähnlichem auseinandergehalten.) Nun gehts eins vorwärts im Array, L+1=R, ein Blatt, R < Elter-R, alles in Butter, ausgeben und weiter. Element 2 hat nun L=4 und das ist größer als das Eltern-R. Du musst jetzt vom Stack soviel abbauen bis das R kleiner als das Stack-R wird oder der Stack leer ist. Element 2 kommt aber nicht auf den Stack, weil dessen L+1=R ist, es also nur ein Blatt ist. Angenommen, es gäbe kein E2, dann ist dein Array zu Ende, aber der Stack ist noch nicht leer. Der muss nun noch abgebaut werden und dir offenen ul/li-Elemente geschlossen werden. Das Abbauen am Ende muss keine eigene Routine sein. Du könntest am Array-Ende ein Pseudo-Element erzeugen, dessen L und R = PHP_INT_MAX sind. Damit baut es den Stack auch komplett ab.

dedlfix.