Newsgroup: it.comp.www.php
Titolo: array gerarchico... funzione ricorsiva

salve,
ho un problemino con una funzione ricorsiva..
ho un array che identifica una struttura gerarchica in questo modo:
id_parent id_child nome
     0         1    Valore1
     1         2    Valore2
     2         3    Valore3
     2         4    Valore4
     4         5    Valore5
vorrei riconfigurare tale array in modo tale da renderlo rappresentativo 
della reale struttura gerarchica.. e quindi ottenere:
0 -> Valore1
|_ 1 -> Valore2
|_ 2 -> Valore3
    |_ 3 -> Valore4
    |_ 4 -> Valore5
       |_5 -> Valore6
tenendo in considerazione che il numero di inclusioni e teoricamente 
infinito...
ipotizzando che il primo array sia $arrRelation
vorrei darlo in pasto ad una fn getTree()
che mi dia come valore di return un $arrTree
qualcuno ha mai fatto qualcosa di simile?
Io sto' avendo qualche problema nell'impostare un processo logico 
corretto...
grazie
simple_maL

 infinito...
[..]
da dove ti arriva questo array?
comunque non e' difficile..
cerchi il? nod[oi] root e poi lo popoli scorrendo quante volte serve l'array
originale..
prova a farlo da solo e se vuoi poi posta cosi' proviamo a migliorarlo..
-- 
www.iuz-lab.info

 originale..
effettivamente ho dimenticato di segnalare un prob di fondo....
nell'es ho messo 1 solo nodo di partenza,
ma in realtà ne posso avere + di uno nello stesso array...
cioè posso avere
0
   1
     2
   3
     4
     5
      6
7
   8
     9

 ma in realtà ne posso avere + di uno nello stesso array...
La lista e' ordinata con i nodi parent prima dei children?
'bye

Agostino De Matteis ha scritto:

no, è estratta secondo particolari algoritmi e me la ritrovo non ordinata..
stavo pensando di scorrere tutto l'array ed assegnare dei bookmark di 
livello ad ogni record una volta individuata la sua posizione gerarchica 
attraverso un secondo ciclo di verifica nello stesso array...
potrebbe essere una soluzione?
simple_maL

 
Non ho capito bene cosa devi farci dopo, o come deve risultare l'array 
finale (come esempio va benissimo un array "finito" scritto in php)

 potrebbe essere una soluzione?
Bisognerebbe vedere il codice :-)
Un'altra idea potrebbe essere questa:
// array originale
$sr=Array();
// un item e' un array con items
//  0          1     2
// parent | id | val
$src[]=Array(0, 1, "a");
$src[]=Array(1, 3, "aa");
$src[]=Array(3, 7, "aaa");
$src[]=Array(1, 4, "ab");
$src[]=Array(2, 5, "ba");
$src[]=Array(0, 2, "b");
$src[]=Array(2, 6, "bb");
$src[]=Array(6, 8, "bba");
$target=reArray($src);
print "from<br/>\n";
print_r($src);
print "to<br/>\n";
print_r($target);
function reArray($sr){
// copia per elaborazione
$srt=Array();
$srt=$sr;
// array finale:
// id | value | children
$ds=Array();
// id inseriti
$inid=Array();
// percorso per arrivare ad un nodo
$path=Array();
$dsc=0; // counter array finale
while(true){
	// prende il primo elemento togliendolo dall'array
	$ce=array_shift($srt);
	if($ce==null){ 
		// non ci sono piu' elementi nell'array 
		// quindi fine loop
		break;
	} 	
	// parent dell'elemento corrente
	$par=$ce[0];
	if($par==0){ // root
		// essendo una root viene inserita subito
		$ds[$dsc][0]=$ce[1]; // id
		$ds[$dsc][1]=$ce[2]; // valore
		$ds[$dsc][2]=Array(); // children
		// segnala id inserito
		$inid[$ce[1]]=$dsc;
		// path per arrivare all'elemento
		$path[$ce[1]]=Array();
		// posizione = root
		$path[$ce[1]][0]=$dsc;
		$dsc++;
	} else {
		// non e' una root
		if(!isset($inid[$par])){ // parent non ancora inserito
			// non processa adesso l'elemento quindi lo rimette
			array_push($srt, $ce); // in fondo all'array
		} else { // parent gia' inserito
			// path per giungere al parent
			$cpath=$path[$par];
			// primo elemento del path e' una 
			$parentn=array_shift($cpath); // root
			// root di partenza
			$parent=&$ds[$parentn];
			// path per l'elemento corrente
			$path[$ce[1]]=Array();
			// primo elemento e' la root
			array_push($path[$ce[1]], $parentn);
			// percorre il path per arrivare al parent
			foreach($cpath as $cp){
				// memorizza il passo nel path dell'elemento corrente
				array_push($path[$ce[1]], $cp);
				// prossimo passo
				$parent=&$parent[2][$cp];
			}
			// ora abbiamo il parent
			// inserimento dell'elemento corrente
			$cpi=Array();
			$cpi[0]=$ce[1];
			$cpi[1]=$ce[2];
			$cpi[2]=Array();
			$parent[2][]=$cpi;
			// sua posizione tra i children
			$n=count($parent[2]);
			// ultimo passo nel path per giungere all'elemento
			array_push($path[$ce[1]], $n-1);
			// segnala l'elemento come inserito
			$inid[$ce[1]]=$ce[1];
		}		
	}
}
return $ds;
}
La funzione fa uso di alcuni array di controllo, quindi se hai problemi di 
memoria e' meglio usarne un'altra :-)
'bye

 Complica un po' le cose.
ciao, ho visto solo ora la tua reply!
Grazie mille per la pazienza che hai avuto nello scrivere tutto il 
"papello" di codice...
lo provo al più presto e ti faccio sapere...
grazie ancora!!!
Ciao
simple_maL

 'bye
la vedo un'po' troppo compicata.. stasera provo a trovare un modo migliore..
-- 
www.iuz-lab.info