my $array = [[apple, a1], [apple, a2], [apple, a3]]; my %hash = (); foreach (@{$array}) { $hash{$_->[0]} = [] unless defined($hash{$_->[0]}); push (@{$hash{$_->[0]}}, $_->[1]); } #### use List::Util qw(reduce); my $array = [[apple, a1], [apple, a2], [apple, a3]]; my $result = []; unshift(@$array, []); push @$result, reduce { push(@$a, $b->[0]) unless exists $a->[0]; push(@$a, $b->[1]); $a; } @$array;