Bạn có thể thử Arrays::Utils
, và nó làm cho nó trông đẹp và đơn giản, nhưng nó không làm bất kỳ phép thuật mạnh mẽ nào ở mặt sau. Dưới đây là đoạn code array_diffs
:
sub array_diff(\@\@) {
my %e = map { $_ => undef } @{$_[1]};
return @{[ (grep { (exists $e{$_}) ? (delete $e{$_}) : (1) } @{ $_[0] }), keys %e ] };
}
Kể từ Arrays::Utils
không phải là một mô-đun tiêu chuẩn, bạn cần phải tự hỏi mình nếu nó có giá trị các nỗ lực để cài đặt và duy trì mô đun này.Nếu không, nó khá gần với câu trả lời của DVK.
Có một số điều bạn phải xem và bạn phải xác định những gì bạn muốn làm trong trường hợp cụ thể đó. Giả sử:
@array1 = qw(1 1 2 2 3 3 4 4 5 5);
@array2 = qw(1 2 3 4 5);
Các mảng này có giống nhau không? Hay chúng khác nhau? Chúng có cùng giá trị, nhưng có các bản sao trong @array1
và không phải là @array2
.
Điều này thì sao?
@array1 = qw(1 1 2 3 4 5);
@array2 = qw(1 1 2 3 4 5);
Tôi sẽ nói rằng các mảng này giống nhau, nhưng Array::Utils::arrays_diff
yêu cầu khác biệt. Điều này là do Array::Utils
giả định rằng không có mục nhập trùng lặp nào.
Và, ngay cả Câu hỏi thường gặp Perl được chỉ ra bởi mob cũng nói rằng Giả định rằng mỗi phần tử là duy nhất trong một mảng nhất định. Đây có phải là một giả định bạn có thể thực hiện?
Không có vấn đề gì, băm là câu trả lời. Thật dễ dàng và nhanh chóng để tìm kiếm một băm. Vấn đề là bạn muốn làm gì với các giá trị duy nhất.
Dưới đây là một giải pháp vững chắc, cho rằng bản sao không quan trọng:
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
}
}
Nếu trùng lặp thành vấn đề, bạn sẽ cần một cách để đếm chúng. Dưới đây là sử dụng bản đồ không chỉ để tạo ra một băm keyed bởi mỗi phần tử trong mảng, nhưng cũng đếm các bản sao trong mảng:
my %array1_hash;
my %array2_hash;
map { $array1_hash{$_} += 1 } @array1;
map { $array2_hash{$_} += 2 } @array2;
Bây giờ, bạn có thể đi qua từng băm và xác minh rằng không chỉ các phím tồn tại , nhưng mà mục của họ phù hợp với
for my $key (keys %array1_hash) {
if (not exists $array2_hash{$key}
or $array1_hash{$key} != $array2_hash{$key}) {
return 1; #Arrays differ
}
}
Bạn chỉ sẽ thoát khỏi vòng lặp for nếu tất cả các mục trong %array1_hash
phù hợp với mục tương ứng của họ trong %array2_hash
. Bây giờ, bạn phải cho thấy rằng tất cả các mục nhập trong %array2_hash
cũng khớp với các mục nhập của chúng trong %array1_hash
và rằng %array2_hash
không có nhiều mục nhập hơn. May mắn thay, chúng tôi có thể làm những gì chúng tôi đã làm trước đây:
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
}
lẽ bạn có thể gửi mã vòng lặp lồng nhau thực tế mà bạn' đã có cho đến nay, điều đó sẽ giúp chúng tôi giúp bạn tìm một cách tốt hơn (nếu có). –
Nếu tôi là bạn, tôi sẽ bắt đầu với CPAN. Hãy xem 'Danh sách :: So sánh' - và đặc biệt, phần ở dưới cùng "Nếu bạn thích danh sách :: So sánh, bạn sẽ yêu ..." Nghe có vẻ như bạn có thể muốn tìm một cái gì đó được triển khai trong C thay vào đó hơn là Perl tinh khiết. http://search.cpan.org/perldoc/List::Compare – Telemachus
Bạn có nghĩa là bạn cần phải biết nếu một mảng là một tập con của người kia? Hoặc nếu chúng chính xác như nhau? Hoặc nếu chúng có cùng yếu tố, nhưng theo thứ tự khác? Và bạn có cần biết những yếu tố nào bị thiếu hoặc chỉ là chúng không giống nhau? – Schwern