my $input = {
'Sally Smith' => { parents => ['Bob Smith', 'Rhonda Smith']},
'Betty Freeman' => { parents => ['Earl Freeman', 'Harmony Ellis']},
'Betty Boop' => { parents => ['Rhonda Smith', 'Louis McFern']},
'Jim Morris' => { parents => ['Betty Boop', 'John Wayne']},
};
####
my $people = {};
for my $m (keys %$input) {
add_person($people,$m, parents => $input->{$m}{parents});
for my $p (@{ $input->{$m}{parents} }) {
add_person($people,$p,children => $m);
}
}
sub add_person {
my ($people,$name,%params) = @_;
if(! defined $people->{$name}) {
$people->{$name} = { children => [], parents => [] };
}
for my $par (keys %params) {
push @{ $people->{$name}{$par} },
ref($params{$par}) eq "ARRAY" ? @{$params{$par}} : $params{$par};
}
}
####
{
"Betty Boop" => { children => ["Jim Morris"], parents => ["Rhonda Smith", "Louis McFern"], },
"Betty Freeman" => { children => [], parents => ["Earl Freeman", "Harmony Ellis"] },
"Bob Smith" => { children => ["Sally Smith"], parents => [] },
"Earl Freeman" => { children => ["Betty Freeman"], parents => [] },
"Harmony Ellis" => { children => ["Betty Freeman"], parents => [] },
"Jim Morris" => { children => [], parents => ["Betty Boop", "John Wayne"] },
"John Wayne" => { children => ["Jim Morris"], parents => [] },
"Louis McFern" => { children => ["Betty Boop"], parents => [] },
"Rhonda Smith" => { children => ["Sally Smith", "Betty Boop"], parents => [] },
"Sally Smith" => { children => [], parents => ["Bob Smith", "Rhonda Smith"] },
}
####
for my $top_level (sort keys %$people) {
next if @{ $people->{$top_level}{parents} };
print_level($people,$top_level,0);
}
sub print_level {
my ($people,$name,$level) = @_;
print " "x$level,$name,"\n";
for my $child (@{ $people->{$name}{children} }) {
print_level($people,$child,$level+1);
}
}
####
Bob Smith
Sally Smith
Earl Freeman
Betty Freeman
Harmony Ellis
Betty Freeman
John Wayne
Jim Morris
Louis McFern
Betty Boop
Jim Morris
Rhonda Smith
Sally Smith
Betty Boop
Jim Morris