I have a bunch of name-parentname pairs, that I\'d like to turn into as few heirarchical tree structures as possible. So for example, these could be the pairings:
Old question, but I too had to do this and the examples with recursion gave me a headache. In my database we have a locations
table, which was a loca_id
PK (Child) and self referencing loca_parent_id
(Parent).
The aim is to represent this structure in HTML. The simple query can of couyrse return the data is some fixed order but I found not well enough to display such data in a natural way. What I really wanted was Oracle tree walk handling with LEVEL
to help with display.
I decided to use the idea of a 'path' to uniquely identify each entry. For example:
Sorting the array by the path should make it easier to process for meaningful display.
I realise that use of associative arrays and sorts is cheating as it hides the recursive complexity of the operations, but to me this look simpler:
=$rowdata['loca_id']?>
=$rowdata['loca_path']?>
=$rowdata['loca_type']?>
=$rowdata['loca_status']?>
prepare($sql);
$stmt->execute();
$result = $stmt->get_result();
$data = $result->fetch_all(MYSQLI_ASSOC);
$printed = array();
// To get tree hierarchy usually means recursion of data.
// Here we will try to use an associate array and set a
// 'path' value to represent the hierarchy tree in one
// pass. Sorting this array by the path value should give
// a nice tree order and reference.
// The array key will be the unique id (loca_id) for each row.
// The value for each key will the complete row from the database.
// The row contains a element 'loca_path' - we will write the path
// for each row here. A child's path will be parent_path/child_name.
// For any child we encounter with a parent we look up the parents path
// using the loca_parent_id as the key.
// Caveat, although tested quickly, just make sure that all parents are
// returned first by the query.
foreach ($data as $row)
{
if ( $row['loca_parent_id'] == '' ) // Root Parent
{
$row['loca_path'] = $row['loca_name'] . '/';
$printed[$row['loca_id']] = $row;
}
else // Child/Sub-Parent
{
$row['loca_path'] = $printed[$row['loca_parent_id']]['loca_path'] . $row['loca_name'] . '/';
$printed[$row['loca_id']] = $row;
}
}
// Array with paths built, now sort then print
array_multisort(array_column($printed, 'loca_path'), SORT_ASC, $printed);
foreach ( $printed as $prow )
{
print_row ( $prow );
}
?>