Вот пример использования each_arrayref
из List :: MoreUtils .
sub diff_array{
use List::MoreUtils qw'each_arrayref';
return unless @_ && defined wantarray;
my @out;
my $iter = each_arrayref(@_);
my $index = 0;
while( my @current = $iter->() ){
next if all_same(@current);
unshift @current, $index;
push @out, \@current;
}continue{ ++$index }
return @out;
}
Эта версия должна быть быстрее, если вы собираетесь использовать ее для определения количества различий часто. Выход точно такой же. Просто не нужно так усердно работать при возврате числа.
Подробнее о wantarray
.
sub diff_array{
use List::MoreUtils qw'each_arrayref';
return unless @_ && defined wantarray;
my $iter = each_arrayref(@_);
if( wantarray ){
# return structure
my @out;
my $index = 0;
while( my @current = $iter->() ){
next if all_same(@current);
unshift @current, $index;
push @out, \@current;
}continue{ ++$index }
return @out;
}else{
# only return a count of differences
my $out = 0;
while( my @current = $iter->() ){
++$out unless all_same @current;
}
return $out;
}
}
diff_array
использует подпрограмму all_same
, чтобы определить, совпадают ли все текущие списки элементов.
sub all_same{
my $head = shift;
return undef unless @_; # not enough arguments
for( @_ ){
return 0 if $_ ne $head; # at least one mismatch
}
return 1; # all are the same
}
Чтобы получить только количество различий:
print scalar diff_array \@array1, \@array2;
my $count = diff_array \@array1, \@array2;
Чтобы получить список отличий:
my @list = diff_array \@array1, \@array2;
Чтобы получить оба:
my $count = my @list = diff_array \@array1, \@array2;
Выход для введенного вами ввода:
(
[ 1, 'B', 'C' ],
[ 2, 'C', 'H' ],
[ 5, 'F', 'G' ]
)
Пример использования
my @a1 = qw'A B C D E F';
my @a2 = qw'A C H D E G';
my $count = my @list = diff_array \@a1, \@a2;
print "There were $count differences\n\n";
for my $group (@list){
my $index = shift @$group;
print " At index $index\n";
print " $_\n" for @$group;
print "\n";
}