2011-01-26 21 views
14

Giả sử tôi có một mảng các số và tôi muốn đảm bảo rằng tất cả các mùa thu trong một trong những bộ (x, y, z), tôi đang kiểm tra mà đánh giá lại sau để 0:Có một toán tử perl "không trong" không?

scalar (grep { $_ ne x && $_ ne y && $_ ne z } @arr) 

được chỉ tự hỏi nếu nó sẽ không được dễ dàng hơn nếu chúng ta có "iN" và "NOT iN" khai thác sql-như trong perl quá ..

scalar (grep { $_ NOT IN (x,y,z) } @arr) 

Hoặc là có một đã ??

Cảm ơn, Trinity

Trả lời

14

Một cách thông thường để giải quyết này là sử dụng một hash:

my %set = map {$_ => 1} qw(x y z); # add x, y and z to the hash as keys 
            # each with a value of 1 

my @not_in_set = grep {not $set{$_}} @arr; 
2
use List::Member; 
my $target = 'bar'; 
my @look_in = ('foo','baz','bar','etc'); 

if(member($target, @look_in) + 1) { 
print "It's a member of the array\n"; 
} 

Điều đó có thể làm các trick

+0

Đó là thư viện tiện dụng, cảm ơn bạn :) – trinity

15

Các thư viện List::Util hoặc List::MoreUtils rất hữu ích ở đây để kiểm tra tư cách thành viên trong danh sách, nơi bạn không quan tâm đến chính các giá trị, mà chỉ đơn giản là sự tồn tại. Đây là những hiệu quả hơn so với grep, bởi vì họ dừng vòng lặp thông qua danh sách ngay sau khi một kết hợp được tìm thấy, mà thực sự có thể tăng tốc độ với những danh sách dài. Hơn nữa các mô-đun này được viết bằng C/XS, nhanh hơn bất kỳ thực thi thuần túy nào.

use List::MoreUtils 'any'; 

my @list = qw(foo bar baz); 

my $exists = any { $_ eq 'foo' } @list; 
print 'foo ', ($exists ? 'is' : 'is not'), " a member of the list\n"; 

$exists = any { $_ eq 'blah' } @list; 
print 'blah ', ($exists ? 'is' : 'is not'), " a member of the list\n"; 

(Nếu bạn bị hạn chế chỉ sử dụng các module đi kèm với lõi Perl, bạn có thể sử dụng first trong Danh sách :: util - nó lần đầu tiên xuất xưởng với perl trong 5.7.3.)

+0

Xin chào, cảm ơn, điều này có vẻ là một lựa chọn tốt! – trinity

+0

IMO này phải là câu trả lời được lựa chọn – andrefs

11

Nếu bạn đang sử dụng Perl 5.10 trở lên (hoặc sẵn sàng sử dụng tính năng thử nghiệm trong perl 5.18 trở lên), toán tử Smart Match sẽ thực hiện chính xác những gì bạn đang tìm kiếm.

# if Perl 5.18 or higher; otherwise not needed 
no warnings 'experimental::smartmatch'; 

my @filter = qw(X Y Z); 
my $not_in_filter = scalar grep { ! ($_ ~~ @filter) } @array; 

Nếu bộ lọc và/hoặc @array lớn, có thể chậm, tuy nhiên, do nó là O (N^2). Trong trường hợp đó, bạn vẫn có thể sử dụng phù hợp với thông minh, và chỉ cần thay đổi bộ lọc của bạn:

my %filter = map { $_ => 1 } qw(X Y Z); 
my $not_in_filter = scalar grep { ! ($_ ~~ %filter) } @array; 

Xem Smart Matching in Detail trong perldoc perlsyn để biết thêm.

Ngoài ra, nếu bạn cần hỗ trợ các phiên bản perl giữa 5.10 và 5.18, hãy xem xét sử dụng mô-đun cpan experimental. Điều này hiện kiểm tra phiên bản và bao gồm các 'không có cảnh báo' nếu nó tìm thấy một phiên bản Perl đòi hỏi nó.

use experimental 'smartmatch'; 

Xem: https://search.cpan.org/~leont/experimental-0.016/lib/experimental.pm

+0

Cảm ơn @ Robert, ~~ là một cái gì đó mới với tôi !! – trinity

+3

@trinity Và tiếc là dòng sản phẩm tính năng smartmatch đã được đánh dấu là thử nghiệm trong perl 5.18.0, vì vậy có thể bạn không nên bắt đầu sử dụng nó. –

4

Nếu có ít hơn một vài triệu thứ khác nhau trong mảng đó, bạn cũng có thể sử dụng phương pháp sách giáo khoa của sự khác biệt thiết lập sử dụng một băm:

my %seen; 
@seen{ @arr } =(); # Create a key for every distinct value in @arr 
delete @seen{ qw(x y z) }; # And remove the ones for x, y, and z 

if (keys %seen) { 
    # There was something in @arr that's not x, y, or z 
} else { 
    # There wasn't 
} 
+0

Wow @hobbs, cách tiếp cận khá khác, cảm ơn bạn :) – trinity

3
my $target = 'bar'; 
my @look_in = ('foo','baz','bar','etc'); 
if($target ~~ @look_in) { 
    print "target is in array "; 
} 

~~ nằm trong mảng

my $target = 'bar'; 
my @look_in = ('foo','baz','bar','etc'); 
if(not $target ~~ @look_in) { 
    print "target is not in array"; 
} 

này được gọi là smartmatch, một số người khuyên bạn không nên sử dụng chúng, nhưng công việc làm việc khá tốt đẹp với danh sách các chuỗi.

Các vấn đề liên quan