Вы можете попробовать Arrays::Utils
, и это заставляет его выглядеть красиво и просто, но на заднем конце он не обладает мощной магией. Вот array_diffs
код:
sub array_diff(\@\@) {
my %e = map { $_ => undef } @{$_[1]};
return @{[ (grep { (exists $e{$_}) ? (delete $e{$_}) : (1) } @{ $_[0] }), keys %e ] };
}
Поскольку Arrays::Utils
не является стандартным модулем, вы должны спросить себя, если это стоит усилий, чтобы установить и поддерживать этот модуль.В противном случае это довольно близко к ответу DVK.
Есть определенные вещи, за которыми вы должны следить, и вы должны определить, что вы хотите сделать в этом конкретном случае. Скажем:
@array1 = qw(1 1 2 2 3 3 4 4 5 5);
@array2 = qw(1 2 3 4 5);
Являются ли эти массивы одинаковыми? Или они разные? Они имеют одинаковые значения, но есть дубликаты в @array1
, а не @array2
.
Что относительно этого?
@array1 = qw(1 1 2 3 4 5);
@array2 = qw(1 1 2 3 4 5);
Я бы сказал, что эти массивы являются одинаковыми, но Array::Utils::arrays_diff
просит отличаться. Это связано с тем, что Array::Utils
предполагает, что дубликатов нет.
И даже в Perl часто задаваемые вопросы mob также говорит, что Предполагается, что каждый элемент уникален в заданном массиве. Это предположение, которое вы можете сделать?
Независимо от того, хеши являются ответом. Легко и быстро найти хэш. Проблема в том, что вы хотите делать с уникальными значениями.
Вот твердое решение, которое принимает на себя дубликаты не имеют значения:
sub array_diff {
my @array1 = @{ shift() };
my @array2 = @{ shift() };
my %array1_hash;
my %array2_hash;
# Create a hash entry for each element in @array1
for my $element (@array1) {
$array1_hash{$element} = @array1;
}
# Same for @array2: This time, use map instead of a loop
map { $array_2{$_} = 1 } @array2;
for my $entry (@array2) {
if (not $array1_hash{$entry}) {
return 1; #Entry in @array2 but not @array1: Differ
}
}
if (keys %array_hash1 != keys %array_hash2) {
return 1; #Arrays differ
}
else {
return 0; #Arrays contain the same elements
}
}
Если дубликаты имеют значение, вам нужен способ, чтобы сосчитать их. Вот с помощью карты не только для создания хэша заклиненного каждого элемента в массиве, но и сосчитать дубликаты в массиве:
my %array1_hash;
my %array2_hash;
map { $array1_hash{$_} += 1 } @array1;
map { $array2_hash{$_} += 2 } @array2;
Теперь вы можете пройти через каждый хэш и убедитесь, что не только существуют ключи , но их данные соответствуют
for my $key (keys %array1_hash) {
if (not exists $array2_hash{$key}
or $array1_hash{$key} != $array2_hash{$key}) {
return 1; #Arrays differ
}
}
Вы выйдете только для цикла, если все записи в %array1_hash
соответствуют их соответствующие записи в %array2_hash
. Теперь вы должны показать, что все записи в %array2_hash
также соответствуют их записям в %array1_hash
и что %array2_hash
не имеет других записей. К счастью, мы можем сделать то, что мы сделали до этого:
if (keys %array2_hash != keys %array1_hash) {
return 1; #Arrays have a different number of keys: Don't match
}
else {
return; #Arrays have the same keys: They do match
}
Может быть, вы могли бы разместить фактический вложенный код цикла, что вы» до сих пор, это поможет нам помочь вам найти лучший способ (если таковой есть). –
Если бы я был вами, я бы начал с CPAN. Взгляните на «Список :: Сравнить» - и особенно раздел внизу «Если вам нравится список :: Сравнить, вы полюбите ...» Похоже, вы можете искать что-то, реализованное на C, скорее чем чистый Perl. http://search.cpan.org/perldoc/List::Compare – Telemachus
Вы имеете в виду, что вам нужно знать, является ли один массив подмножеством другого? Или если они ровно равны? Или если у них одни и те же элементы, но в другом порядке? И вам нужно знать, какие элементы отсутствуют или просто они не то же самое? – Schwern