[PHP / Recursie] Alle kinderen van een parent opzoeken

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
In onderstaande array wordt voor elk item aangegeven tot welke parent deze behoort. Daaronder staat een functie waarmee ik een array maak waar voor elke parent staat welke kinderen hij heeft:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$nav[1] = array('nid' => 1, 'pid' => 0);
$nav[2] = array('nid' => 2, 'pid' => 1);
$nav[3] = array('nid' => 3, 'pid' => 1);
$nav[4] = array('nid' => 4, 'pid' => 3);
$nav[5] = array('nid' => 5, 'pid' => 4);
$nav[6] = array('nid' => 6, 'pid' => 4);
$nav[7] = array('nid' => 7, 'pid' => 5);

function child_table() {
  global $nav;

  foreach ($nav as $id => $item) {
    $pid = $item['pid'];
    if (isset($children[$pid])) {
      $children[$pid][] = $id;
    }
    else {
      $children[$pid] = array($id);
    }
  }

  return $children;
}

function all_children_threaded($item) {
  global $nav;
  
  $child_table = child_table();
  foreach ($child_table[$item] as $child_id) {
    $child = $nav[$child_id];
    $children[] = $child_id;
    
    if (array_key_exists($child_id, $child_table)) {
      $children[$item] = array_merge($children, all_children_threaded($child_id));
    }
  }
  
  return $children;
}

Het probleem is dat ik de output van all_children_threaded maar niet goed krijg. De bedoeling is een array als (voor print_r(all_children_threaded(1)):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Array
(
    [2] =>
    [3] => Array
        (
            [4] => Array
                (
                    [5] => Array
                        (
                            [7] =>
                        )
                    [6] => Array
                )
        )
)

Ik heb al verschillende dingen geprobeerd, bijvoorbeeld regel 31 veranderen in $children[$item] = $child_id, maar dit geeft niet het gewenste resultaat. Wie kan mij zeggen wat ik verkeerd doe?

[ Voor 9% gewijzigd door Reveller op 14-08-2005 14:43 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • DJ Buzzz
  • Registratie: December 2000
  • Laatst online: 19-09 08:24
Als ik het zo snel bekijkt, lijkt het alsof je bij 4 b.v. tegelijk er een waarde aan wilt hangen en ook nog een array, dat lijkt me redelijk onmogelijk. Ik zou gebruik maken van associatieve arrays, zoals
[value] = 3
[child] = Array(...

Waarbij child een lege array bevat als er geen kinderen bevat (of null, of welke waar je dan ook maar wilt).

Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Dat is een foutje in mijn startpost ... array is inmiddels aangepast :)

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • Vesta
  • Registratie: November 2004
  • Niet online
Je maakt een denkfout in de functie all_children_threaded. Vergelijk die met onderstaande code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function all_children_threaded($item) { 
  global $nav; 
   
  $child_table = child_table(); 
  
  $children = array(); // definieer array
  
  foreach ($child_table[$item] as $child_id) { 
    // $child = $nav[$child_id]; // wordt niet gebruikt
    // $children[] = $child_id;  // overbodig
     
    if (array_key_exists($child_id, $child_table)) { 
      //$children[$item] = array_merge($children, all_children_threaded($child_id));
      $children[$child_id] = all_children_threaded($child_id); 
    } else {
        $children[$child_id] = array(); // $child_id heeft geen children
    }
  } 
   
  return $children;
}
Ik kan niet precies uitleggen wat je precies verkeerd doet, hopelijk snap je de verschillen. In de foreach ga je ieder kind af en kijk je of deze kinderen heeft. Als dat zo is, moet je dat opslaan in $children[$child_id] en niet in $children[$item], welke een niveau hoger zit (zeg maar de opa). Als $child_id geen kinderen heeft, kun je dat aangeven door van $children[$child_id] een lege array te maken, of een boolean true.