Вот функция, которую я использовал много, много раз.
sub compute_sets {
my ($ra, $rb) = @_;
my (@a, @b, @ab, %a, %b, %seen);
@a{@$ra} = ();
@b{@$rb} = ();
foreach (keys %a, keys %b) {
next if $seen{$_}++;
if (exists $a{$_} && exists $b{$_}) {
push(@ab, $_);
}
elsif (exists $a{$_}) {
push(@a, $_);
}
else {
push(@b, $_);
}
}
return(\@a, \@b, \@ab);
}
Возвращает ссылки на массивы, содержащие элементы в первом / втором / обоих списках:
my @new = qw/a b c d e/;
my @old = qw/a b d e f/;
my ($new_only, $old_only, $both) = compute_sets(\@new, \@old);
say 'new only: ', join ' ', @$new_only; # c
say 'old only: ', join ' ', @$old_only; # f
say 'both: ', join ' ', @$both; # e a b d