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}; } }