my @d = map {[split /-/]} @data; foreach my $i (reverse (0 .. 2)) { my @t; push @{$t[$$_[$i]]}, $_ for @d; @d = map {@{$_ || []}} @t; } @data = map {join "-", @$_} @d;