[PHP] Sorteer een array van objecten op object-property

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • gvanh
  • Registratie: April 2003
  • Laatst online: 02-12-2023

gvanh

Webdeveloper

Topicstarter
Hallo!

Ik zit met een programmeer-technisch probleem. Alhoewel... het is niet eens echt een probleem. Het lijkt echter dat mijn gevonden oplossing nou niet direct de meest efficiënte is ... vandaar.

Om enige achter-grond te geven, ik heb een MySQL tabel met 'mappen', vergelijkbaar met een hierarchie van mappen die je ook in windows zou terugvinden. Hiervoor gebruik ik de volgende indeling:

code:
1
2
3
folderID  (INT)      PRI
parentID (INT)
name


Nu wil ik graag een HTML select-box maken, waarin de hierarchie van de mappen duidelijk naar voren komt. Dat zou dus ongeveer een indeling krijgen als volgt:

code:
1
2
3
4
5
6
7
HOOFDMAP
-- SUBMAP1
---- SUBSUBMAP1
-- SUBMAP2
---- SUBSUBMAP2
------ SUBSUBSUBMAP2
etc.


Nu is de eerste stap, dat ik alle mappen uit de database haal. Met mijn standaard set van Controller-class en Entity-class levert dat een array op met de FOLDER objecten. Ieder folder object heeft de member-vars, zoals die in de table voorkomen.

Nog even, alhoewel wellicht overbodig:

code:
1
2
3
4
5
class Folder {
   var $folderID = 0;
   var $parentID = 0;
   var $name = "";
}


Nu moet ik dus de mappen gaan sorteren, zodat ze in de juiste hierarchie terechtkomen en er - afhankelijk van het niveau van de map - een prefix voor de naam komt (--).

In mijn huidige oplossing, heb ik daarvoor een recursieve functie die begint bij de mappen waarvoor geldt parentID = 0, dit zijn immers de hoofdmappen. Vervolgens worden steeds alle submappen van de betreffende hoofdmap hieronder toegevoegd, waarin per map wordt bekeken of deze eventueel ook weer submappen heeft.

Dit lijkt allemaal nog redelijk 'straight forward'. Nu komt het echter. Wanneer ik ga kijken of een map in aanmerking komt als submap van de betreffende map, ga ik in een foreach() loop steeds door alle mappen heen. Dat wil zeggen dat er - volgens mij - veel tijd verloren gaat in het doorlopen van de hele array. Die functie ziet er ongeveer zo uit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function getChildren ( $given_parentID, $all_folders ) {

   $temp_array = Array();

   foreach ( $all_folders as $folder ) {

      if ( $folder->parentID == $given_parentID ) {

         $temp_array[] = $folder;

      }

   }

   return $temp_array;

} // end of function getChildren()


Dit lijkt dus niet de meest efficiënte functie, want steeds worden weer alle mappen doorlopen op zoek naar de juiste mappen.

Mijn grote vraag is dus: Kan dit handiger?

Overigens heb ik er in dit voorbeeld voor gekozen om te werken met slechts één MySQL query, dat leek me sneller dat steeds, afhankelijk van de parentID een nieuwe query uit te voeren. Klopt dat?

Ik hoop dat iemand hier zijn ervaring over kan laten spreken.

Alvast bedankt!

Robert-Jan.

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
Wat kan handig zijn: een recursieve functie maken.

Acties:
  • 0 Henk 'm!

  • dingstje
  • Registratie: Augustus 2002
  • Laatst online: 02-01-2024
Je loopt eerst door je lijst en gooit alle mappen samen per ParentID:
PHP:
1
2
3
4
5
6
7
<?php
$lijst = Array();
foreach ($all_folders as $folder) {
$lijst[$folder->parentid][] = $folder->folderid; / *Je zou hier ook gewoon het
Folder object kunnen inproppen */
}
?>


Dan kan je gemakkelijk door die lijst loopen om al je folders te krijgen.

Edit: om het wat duidelijker te maken:

PHP:
1
2
3
4
5
6
7
8
9
10
11
<?php
function getChildren($folderid) {
global $lijst;
if (count($lijst[$folderid]) > 0) {
return $lijst[$folderid];
}
else {
return Array();
}
}
?>


Voor die prefixes begin je gewoon bij $i = 0 bij het maken van je box, per niveau omhoog $i++, per niveau omlaag $i-- en dan je dashes genereren met for().

[ Voor 52% gewijzigd door dingstje op 03-07-2004 18:39 . Reden: layout enzo ]

If you can't beat them, try harder


Acties:
  • 0 Henk 'm!

  • MisterData
  • Registratie: September 2001
  • Laatst online: 29-08 20:29
Ik zie dat je bezig bent met trees in SQL en PHP. Hiervoor zou je misschien beter gebruik kunnen maken van het (iets complexere) zogenaamde 'Celko'-model (omdat ene meneer Celko dat ooit bedacht heeft). Lees daarvoor dit topic maar eens: [rml][ mySql] boomstructuur[/rml] :) Met het parent_id-model dat je nu voor ogen hebt ben je een hoop queries kwijt om te weten wie de parents zijn van een item, bij Celko maar 1.

[ Voor 22% gewijzigd door MisterData op 03-07-2004 19:20 ]


Acties:
  • 0 Henk 'm!

  • onkl
  • Registratie: Oktober 2002
  • Laatst online: 14:45
Die Celko is erg mooi (zijn model dus, pics bevielen minder 8)7 ). Alles is wel gezegd in link van Misterdata, behalve de link naar het originele artikel van Celko.
Kan erg goed uitleggen, voor mooie copy-pastecode daarna naar 't oude GoT topic.
Zijn drie collumns in een een maandblad (DBMS), link 1 stond al in topic waarmee Misterdata aankwam, het vervolg was even zoeken, dus voor 't gemak:
Maart 1996
April 1996
Mei 1996
1996 _/-\o_ Bewijst maar weet dat goede ideeen langer nuttig blijven dan goede computers :Y)

offtopic:
titel is eerlijk gezegd niet alles, ik laat het aan de TS (mag Topic report indienen met evt. voorstel was geloof ik het beleid?), misschien iets met "tree", dan weet iedereen weer waar't over gaat

[ Voor 20% gewijzigd door onkl op 03-07-2004 22:40 . Reden: oftopic additie ]