Baumstruktur aus Strings erstellen

Raven280438

Erfahrenes Mitglied
Hi,

also ich habe ein eindimensionales Array in dem Pfade gespeichert sind. Aus diesen Pfaden möchte ich jetzt gerne ein Baumstruktur erstellen.

z.B. wenn das Array so aussieht:
PHP:
$pfade = array("Ebene1a","Ebene1b/Ebene2a","Ebene1b/Ebene2b","Ebene1b/Ebene2b/Ebene3a","Ebene1c/Ebene2a");
soll die Baumstruktur ungefähr so aussehn:

Code:
Ebene1a
Ebene1b
   Ebene2a
   Ebene2b
      Ebene3a
Ebene1c
   Ebene2a

Die Ebenen sollten dann auch Links haben, in denen der Name der jeweiligen Ebene übergeben werden kann.


Kann mir da jemand weiterhelfen?


Gruß
 
Probier mal Folgendes:
PHP:
$tree = array();
foreach( $pfade as $pfad ) {
	$segments = explode('/', $pfad);
	$c =& $tree;
	foreach( $segments as $segment ) {
		if( isset($c[$segments]) ) {
			$c =& $c[$segment];
		} else {
			$c[$segment] = array();
		}
	}
}
var_dump($tree);
Damit solltest du ein assoziatives Array des Baums erhalten.
 
ah, ok danke.

Jetzt muss ich aus diesem Array irgendwie die Baumstruktur basteln. Sicher wäre eine rekursive Funktion nötig, damit die Pfade eine beliebige Tiefe haben.
 
Ja du wirst einen rekursiven Algorithmus benötigen, der die Knoten der Tiefe nach abläuft. Das Ganze könnte etwa wie folgt aussehen:
PHP:
function foobar( $tree )
{
	if( !is_array($tree) ) {
		return false;
	}
	$retVal = '<ul>';
	foreach( $tree as $key => $val ) {
		$retVal .= '<li>' . htmlspecialchars($key);
		if( !empty($val) ) {
			$retVal .= foobar($val);
		}
		$retVal .= '</li>';
	}
	return $retVal;
}
 
Ok,

Ich hab die Funktion ein bisschen abgeändert, um die veschiedenen Ebenen einzurücken.
PHP:
function foobar($tree,$e) {
		if( !is_array($tree) ) {
			return false;
		}
		$retVal = '';
		foreach( $tree as $key => $val ) {
			for ($i=0;$i<=$e;$i++) {
				$retVal .= '&nbsp;&nbsp;';
			}
			$retVal .= htmlspecialchars($key) . '<br />';
			if( !empty($val) ) {
				$retVal .= foobar($val,$e+1);
			}
		}
		return $retVal;
	}
Die Variable $e ist einfach die Ebene, um pro Ebene 2x &nbsp; davor zu machen.

So richtig scheint die Funktion oder die Schleife zum erstellen des assoziatives Arrays nicht zu funktionieren.

Mein Array sieht so aus:
$pfade = array(
"Ebene1a/Ebene2a/Ebene3a",
"Ebene1a/Ebene2a/Ebene3b",
"Ebene1b",
"Ebene1c");

Daraus wird folgendes gemacht:
Code:
  Ebene1a
    Ebene2a
    Ebene3b
  Ebene2a
  Ebene3a
  Ebene1b
  Ebene1c

Sollte aber eigendlich so aussehen:
Code:
  Ebene1a
    Ebene2a
      Ebene3a
      Ebene3b
  Ebene1b
  Ebeen1c

Kann jemand den Fehler entdecken?
 
Beide Algorithmen waren etwas fehlerhaft. Folgendes funktioniert jedoch nun:
PHP:
function pathlistToTree( $pathlist )
{
	$tree = array();
	foreach( $pathlist as $path ) {
		$segments = explode('/', $path);
		$c =& $tree;
		foreach( $segments as $segment ) {
			if( !isset($c[$segment]) ) {
				$c[$segment] = array();
				$c =& $c[$segment];
			}
		}
	}
	return $tree;
}

function treeToHtmllist( $tree )
{
	if( !is_array($tree) ) {
		return false;
	}
	$retVal = '<ul>';
	foreach( $tree as $key => $val ) {
		$retVal .= '<li>' . htmlspecialchars($key);
		if( !empty($val) ) {
			$retVal .= foobar($val);
		}
		$retVal .= '</li>';
	}
	$retVal .= '</ul>';
	return $retVal;
}
 
Ein kleiner Fehler ist glaube ich in der ersten Funktion: das return muss sicher unter die foreach-Schleife, nicht darein.

Es funktioniert aber bei mir immer noch nicht richtig. Vielleicht liegts an meiner Anpassung.
Hier nochmal meine angepassten Funktionen:
PHP:
function pathlistToTree($pathlist) {
	$tree = array();
	foreach( $pathlist as $path ) {
		$segments = explode('/', $path);
		$c =& $tree;
		foreach( $segments as $segment ) {
			if( !isset($c[$segment]) ) {
				$c[$segment] = array();
				$c =& $c[$segment];
			}
		}
	}
	return $tree;
}

function treeToHtmllist($tree,$e) {
	if( !is_array($tree) ) {
		return false;
	}
	foreach( $tree as $key => $val ) {
		for ($i=0;$i<=$e;$i++) {
			$retVal .= '&nbsp;&nbsp;';
		}
		$retVal .= name_postfach($key).'<br />';
		if( !empty($val) ) {
			$retVal .= treeToHtmllist($val,$e+1);
		}
	}
	return $retVal;
} 

echo treeToHtmllist(pathlistToTree($pfade),0);
Nochmal zur Info: die Vaiable $e ist die Ebene, damit ich sie einrücken kann. Ich möchte keine Liste mit ul und li, sondern einfach nur einrücken.

Nachdem ich mir das Array, welches die erste Funktion zurückgibt, mit print_r angesehn habe, vermute ich den Fehler in dieser Funktion.


Gruß
 
Es gab noch einen weiteren Fehler. Jetzt aber:
PHP:
function pathlistToTree( $pathlist )
{
	$tree = array();
	foreach( $pathlist as $path ) {
		$segments = explode('/', $path);
		$c =& $tree;
		foreach( $segments as $segment ) {
			if( !isset($c[$segment]) ) {
				$c[$segment] = array();
			}
			$c =& $c[$segment];
		}
	}
	return $tree;
}
 
Zurück