T Travoni Medlem sedan okt. 2004 1 556 inlägg Frågan 2 mars 2008 22:47 #1 Jag skulle vilja göra en rekursiv funktion som skapar en ul-li lista utav ett innehåll i en databas.
Det finns bara ett litet krux, noderna innehåller inget "parnet-id" vilket jag tycker försvårar det hela en del. :)
Däremot så hämtas alltid raderna i "rätt ordning" och djupet på noderna (som kanske kan användas i stället).
Tänker mig nåt sånt här:
[B]Namn [red]Djup[/red][/B]
--------------------
Allt [red]0[/red]
Bilar [red]1[/red]
Volvo [red]2[/red]
v70 [red]3[/red]
xc90 [red]3[/red]
Saab [red]2[/red]
Båtar [red]1[/red]
Segelbåtar [red]2[/red]
Motorbåtar [red]2[/red]
spango Medlem sedan juni 2000 8 205 inlägg Behöver inte bli rekursivt. Pseudokod:
previousDepth = -1
för varje rad:
for (; previousDepth > rad.djup; previousDepth--) skriv ut "</ul>"
for (; previousDepth < rad.djup; previousDepth++) skriv ut "<ul>"
skriv ut "<li>" + rad.namn + "</li>"
// avsluta med att stänga alla listor
for (; previousDepth > -1; previousDepth--) skriv ut "</ul>"
red. buggfix
T Travoni Medlem sedan okt. 2004 1 556 inlägg Ok, skall jag göra tre for/while-satser för varje rad?
Typ så här?
{
DataRow dr;
connection.Open();
using (MySqlDataReader reader = command.ExecuteReader) {
while (reader.Read) {
dr = dt.NewRow();
int previousDepth = -1;
while (previousDepth > rad.djup) {
dr("Content") = "</ul>";
previousDepth -= 1;
}
while (previousDepth < rad.djup) {
dr("Content") += "<ul>";
previousDepth += 1;
}
dr("Content") += "<li>" + rad.namn + "</li>";
while (previousDepth > -1) {
dr("Content") += "</ul>";
previousDepth -= 1;
}
dt.Rows.Add(dr);
}
reader.Close();
}
}
spango Medlem sedan juni 2000 8 205 inlägg Nej, den sista loopen, där man räknar ner previousDepth till -1, ska ligga efter att du loopat igenom svaret från databasen, så att man stänger alla ul. Typ efter anropet till reader.Close().
T Travoni Medlem sedan okt. 2004 1 556 inlägg Oki, mycket STORT tack! :f
Funkade klockrent!
Inte för att det spelar någon roll, men funktionen är iterativ, inte rekursiv.
E emission Medlem sedan dec. 1999 6 721 inlägg Som en kul grej provade jag att göra det med webbkontroller i stället.
HtmlGenericControl baseList= new HtmlGenericControl("ol");
HtmlGenericControl currentList =baseList;
HtmlGenericControl listItem=null;
Stack<HtmlGenericControl> stack = new Stack<HtmlGenericControl>();
int currentDepth = 0;
foreach (Item item in items)
{
if (item.Depth > currentDepth)
{
stack.Push(currentList);
HtmlGenericControl newList = new HtmlGenericControl("ol");
listItem.Controls.Add(newList);
currentList = newList;
}
else if (item.Depth < currentDepth)
{
currentList=stack.Pop();
}
HtmlGenericControl listItem = new HtmlGenericControl("li");
listItem.InnerText = item.Name;
currentList.Controls.Add(listItem);
currentDepth=item.Depth;
}
spango Medlem sedan juni 2000 8 205 inlägg Jag har insett att min algoritm är trasig, eller rättare sagt att HTML-koden den genererar är det, eftersom <ul> enbart får innehålla <li>. Alltså borde den genererade koden bli nåt i stil med
<ul>
<li>
Allt
<ul>
<li>
Bilar
<ul>
<li>
Volvo
<ul>
<li>
v70
</li>
<li>
xc90
</li>
</ul>
</li>
<li>
Saab
</li>
</ul>
</li>
<li>
Båtar
<ul>
<li>
Segelbåtar
</li>
<li>
Motorbåtar
</li>
</ul>
</li>
</ul>
</li>
</ul>
Klurigt värre. Jag hinner dessvärre inte fundera på't mer idag.
E emission Medlem sedan dec. 1999 6 721 inlägg Gjorde samma fel och ändrade.
spango Medlem sedan juni 2000 8 205 inlägg Nu är det förvisso på sin höjd enbart av akademiskt intresse, eftersom emissions lösning med webbkontroller är bättre, men så här kan det se ut:
def print_menu(elmts, pos, lvl):
print "<ul>"
while pos < len(elmts) and elmts[pos].depth == lvl:
print "<li>"
print elmts[pos].name
pos += 1
if pos < len(elmts) and elmts[pos].depth > lvl:
pos = print_menu(elmts, pos, elmts[pos].depth)
print "</li>"
print "</ul>"
return pos
# ...
elmts = [
MenuItem("Allt", 0),
MenuItem("Bilar", 1),
MenuItem("Volvo", 2),
MenuItem("v70", 3),
MenuItem("xc90", 3),
MenuItem("Saab", 2),
MenuItem("Båtar", 1),
MenuItem("Segelbåtar", 2),
MenuItem("Motorbåtar", 2),
MenuItem("Ideal", 3),
MenuItem("Uttern", 3),
MenuItem("Segway", 1)
]
print_menu(elmts, 0, elmts[0].depth)