Avatar billede sobazz Nybegynder
07. juli 2002 - 22:04 Der er 3 kommentarer og
1 løsning

Problem med rekursiv funktion

Hej allesammen!

Dette er mit første møde med rekursive funktionsudtryk og alvorlig brug af arrays. Indtil videre er jeg sådan set nået længere end jeg havde regnet med at gøre.

Jeg har en mængde poster i en database. Dataene er fordelt over følgende felter: id, tekst, url, parent, position. Parent er en reference til en anden post i tabellen. Meningen med mit script er hente disse data ud med kun en db-query - dvs. hente dataene ud i en array - og derefter stille dem op på en liste med over og underpunkter. I princippet med en uendelig mængde underniveau.

Resultatet, som det ser ud indtil videre, kan findes her: http://sobazz.dyndns.dk

Problemet er, som det ses på ovenstående adresse, at nogle data bliver hentet ud flere gange. Jeg har forsøgt at dæmme op for det på forskellig vis, men indtil videre uden resultat.

Her er min kode UDEN forsøg på at hindre udskrivning af samme post flere gang:
------------------------------------------------------

$query = mysql_query("SELECT id,tekst,parent,position FROM ".$GLOBALS['conf_table_menu']." ORDER BY parent,position") or die ("Error selecting menu data!");
while($result = mysql_fetch_array($query)){

    $alldata[] = array("id" => $result['id'], "tekst" => $result['tekst'], "parent" => $result['parent'], "position" => $result['position']);

};

function buildTree($leveldata,$alldata) {

    for($i=0;$i<count($leveldata);$i++) {
        unset($buildAgain);
        echo $leveldata[$i]['tekst']."<br>";
        for($ia=0;$ia<count($alldata);$ia++) {
            if(array_search($leveldata[$i]['id'],$alldata[$ia]) == "parent") {
                $arrayName = $leveldata[$i]['id']."Array";
                ${$arrayName}[] = $alldata[$ia];
                $buildAgain = "true";
            } else {
            }       
        }
        if($buildAgain) {
            buildTree($$arrayName,$alldata);
        }
    }
}

buildTree($alldata,$alldata);

--------------------------------------------------------

Og ja - jeg ved godt det er slamkode.... det kan garanteret gøres meget nemmere og meget bedre. Er der nogen, som kan se en løsning på problemet uden alt for store ændringer i scriptet?


Hilsen
Søren. B.
Avatar billede flawless Nybegynder
08. juli 2002 - 03:07 #1
Hmm... jeg var lige ved at skrive et svar, men så faldt jeg over betingelsen "kun en query"... HVORfor? :-)

Dette her:

while($result = mysql_fetch_array($query)){

    $alldata[] = array("id" => $result['id'], "tekst" => $result['tekst'], "parent" => $result['parent'], "position" => $result['position']);

};

Er under alle omstændigheder langsomt. Med mindre der er tale om helt særlige omstændigheder, vil jeg vældigt gerne komme med et svar hvor der er mere end én query :-)
Avatar billede sobazz Nybegynder
08. juli 2002 - 08:58 #2
Ovenstående er ikke så langsomt som utallige sql-queries. Prøv at tænke det ud i sidste konsekvens. Det kan blive til rigtigt mange i længden. At det selfølgelige gør det, fordi der er tale om et relativt simpelt træ, er en anden.

Det var mit mål fra starten at benytte en array - også for at forberede mit på at skrive et forum-system.
Avatar billede flawless Nybegynder
08. juli 2002 - 09:17 #3
Du kunne jo trods alt prøve den nemme version (med mange queries) først, og så se HVOR langsom den er :)

Måske er det ikke så slemt!
Avatar billede sobazz Nybegynder
08. juli 2002 - 14:41 #4
Jeg har rationaliseret udtrykket en smule. Det var fuldt af tåbeligheder. Resultatet af 6 timers søvn er således ikke udeblevet. Nu fungerer funktionen præcis som den skal. Se http://sobazz.dyndns.dk.

Jeg lukker derfor spørgsmålet.

$query = mysql_query("SELECT id,tekst,parent,position FROM ".$GLOBALS['conf_table_menu']." ORDER BY parent,position") or die ("Error selecting menu data!");
while($result = mysql_fetch_array($query)){

    $alldata[] = array("id" => $result['id'], "tekst" => $result['tekst'], "parent" => $result['parent'], "position" => $result['position']);

};

function buildTree($alldata,$id = 0) {
    for($i=0;$i<count($alldata);$i++) {
        if($alldata[$i]['parent']==$id) {
            unset($buildAgain);
            echo $alldata[$i]['tekst']."<br>";
            for($ia=0;$ia<count($alldata);$ia++) {
                if(array_search($alldata[$i]['id'],$alldata[$ia]) == "parent") {
                    $buildAgain = "true";
                    break;
                }    
            }
            if($buildAgain) {
                buildTree($alldata,$alldata[$i]['id']);
            }
        }
    }
}

buildTree($alldata);
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester