As LanX pointed out, you need to convert the bottom-up "Who is my boss" structure
into a top-down "Who are my subordinates" structure, then print the resulting tree.
For example:
use 5.010;
use strict;
use warnings;
# Generalized sample input data (i.e. multiple top-level groups,
# each with multiple independent bosses)...
my %org_chart = (
'1929' => {
'3' => { 'name' => 'Amy', 'boss' => 1929, },
'4425' => { 'name' => 'Dwight', 'boss' => 1 },
'480' => { 'name' => 'Fry', 'boss' => 2 },
'1919' => { 'name' => 'Bender', 'boss' => 2, },
'1929' => { 'name' => 'Professor', 'boss' => 0 },
'3968' => { 'name' => 'Cubert', 'boss' => 1929, },
'1' => { 'name' => 'Hermes', 'boss' => 1929, },
'4' => { 'name' => 'Zoidberg', 'boss' => 1 },
'2' => { 'name' => 'Leela', 'boss' => 1 },
},
'666' => {
'666' => { 'name' => 'Satan', 'boss' => 0 },
'1' => { 'name' => 'Beelzebub', 'boss' => 666 },
'777' => { 'name' => 'Lucky', 'boss' => 1 },
'99' => { 'name' => 'Damien', 'boss' => 666 },
'333' => { 'name' => 'Satan Jr', 'boss' => 0 },
'11' => { 'name' => 'Unlucky', 'boss' => 333 },
}
);
# Convert each top-level group into a tree of subordinates...
for my $group (values %org_chart) {
for my $employee (keys %{$group}) {
# Who is this employee's boss???
my $boss = $group->{$employee}{boss};
# Nothing to do if employee doesn't have a boss...
next if $boss == 0;
# Record that this employee is a subordinate of their boss...
push @{$group->{$boss}{subordinates}}, $group->{$employee};
}
}
# Draw each group's org-chart (horizontally),
# starting with boss-less employees...
for my $group (values %org_chart) {
for my $employee (values %{$group}) {
# Ignore employees who have a boss...
next if $employee->{boss};
# Draw the org chart for employees that don't have a boss...
draw_chart($employee);
}
# Draw gap between groups...
say "";
}
# Draw each employee and their subordinates tree...
sub draw_chart {
my ($root_node, $level) = @_;
$level //= 0;
# Report the employee...
say " |" x $level, "-> ", $root_node->{name};
# Recursively report their subordinates...
for my $subordinate (@{$root_node->{subordinates}}) {
draw_chart($subordinate, $level+1);
}
}