use strict; use warnings; use Data::Dumper; sub unpack_row { my ($hash, @row) = @_; return [ @row, $hash ] unless (ref $hash eq 'HASH'); return map { unpack_row($hash->{$_}, @row, $_) } keys %$hash; } my $hash = { foo => { bar => { bat => 5, bird => 2 } }, goo => { tab => { bird => 2 } }, }; print Dumper($hash); print Dumper(unpack_row($hash, ()));