2010-05-14 34 views
1

我有一個函數使用當量操作者來搜索對象的一個​​匹配的值的陣列,像這樣的匹配可能多個值:搜索對象陣列,用於使用不同的比較運算符

sub find { 
    my ($self, %params) = @_; 
    my @entries = @{ $self->{_entries} }; 

    if ($params{filename}) { 
     @entries = grep { $_->filename eq $params{filename} } @entries; 
    } 
    if ($params{date}) { 
     @entries = grep { $_->date eq $params{date} } @entries; 
    } 
    if ($params{title}) { 
     @entries = grep { $_->title eq $params{title} } @entries; 
    } 
    .... 

我想也能在QR引用變量傳遞在比較中使用,而不是,但我能想到的分離比較的唯一方法就是使用if/else塊,像這樣:

if (lc ref($params{whatever}) eq 'regexp') { 
    #use =~ 
} else { 
    #use eq 
} 

是否有這樣做的一個較短的方式?由於我無法控制的原因,我使用Perl 5.8.8,因此我無法使用智能匹配運算符。

TIA

回答

5

這是Perl,顯然所以有CPAN模塊:Match::Smart。它與Perl 5.10的智能匹配運算符非常類似,只有你鍵入smart_match($a, $b)而不是$a ~~ $b

您不妨比較一下perlsyn documentation for 5.10 smartmatching,因爲Match :: Smart可處理更多情況。

否則,我看不出有什麼毛病:

sub smart_match { 
    my ($target, $param) = @_; 
    if (ref $param eq 'Regexp') { 
     return ($target =~ qr/$param/); 
    } 
    else { 
     return ($target eq $param); 
    } 
} 

@entries = grep { smart_match($_->date, $params{date}) } @entries; 
+1

+1給我介紹一個新的模塊,我可能只需要在$ work上安裝。 – Ether 2010-05-14 02:53:52

+0

現在我知道匹配::智能。哈哈哈。 – darch 2010-05-14 02:58:28

0

我不知道你希望你的最終結果是什麼,但你可以這樣做:

for my $field (qw(filename date title)) { 
    my $p = $param($field}; 
    @entries = (ref($p) eq 'regexp') 
    ? grep { $_->$field =~ /$p/ } @entries 
    : grep { $_->$field eq $p } @entries; 
} 

或者,你甚至可以將你的'eq'比較變成正則表達式,例如:

my $entry = "string to be equal to"; 
my $re = qr/^\Q$entry\E/; 

並且簡化了t他在for循環中的邏輯。