sub flatten { my @ret = (); while (@_) { my $k = shift; if (ref $_[0]) { my $v = shift; push @ret, [ $k, @$_ ] for flatten(@{$v}); } else { push @ret, [ $k ]; # push @ret, [ shift ] while @_ and (! $_[1] or ! ref $_[1]); } } @ret; } use Data::Dumper; print Dumper([flatten(@{$data_struct})]);