my %country= ( 'United States' => { Ohio => { 'Franklin County' => { Columbus => [1, 3.14159, 2.71828], Delaware => [2, 3, 5, 7, 11, 13], }, 'Crawford County' => { Galion => [419, 468, 1708], }, 'Summit County' => [1.59, 2.78, 3.62], }, Iowa => [1.9999, 3], }, 'Jamaica' => [ 4.512, 1.8, 3], ); recursivelyprintsum(0, World => \%country); sub recursivelyprintsum { my ($level, $label, $data) = @_; if (ref $data eq 'ARRAY') { my $value; $value += $_ for @$data; print "\t" x $level; print "$label:\t$value\n"; return $value; } elsif (ref $data eq 'HASH') { print "\t" x $level; print "$label:\n"; my $subtotal; foreach my $unit (keys %$data) { $subtotal += recursivelyprintsum($level + 1, $unit, $$data{$unit}); } print "\t" x $level; print "$label total:\t$subtotal\n"; return $subtotal; } else { # $data must actually be $datum. print "\t" x $level; print "$label:\t$data\n"; return $data; } }