2012-05-03 13 views
1

私は指定された値のハッシュでルックアップを行う "lookup"という名前のサブを持っています。 与えられた値ではなく、パラメータとして渡された値よりも小さい値を探すように要求することができれば、はるかに強力なことに気付きました。演算子をPerlサブルーチンに渡すには?

私はlookupbigger、lookupsmall ..などを作ることができましたが、もっと良い方法があると確信しています。

# lookup id according to the search criteria 
sub lookup { 
    my($data, $lk, $lv) = (@_); 
    my @res; 

    foreach my $key (keys $data) { 
    my $value = $$data{$key}; 
    next unless(defined $$value{$lk}); 
    # this is the line where I want to replace eq with another operator 
    push(@res, $key) if($$value{$lk} eq $lv); 
    } 

    return \@res; 
} 
+0

@TLP質問を実際のコードで更新しました。 – cstamas

答えて

6

を使用するように試みることができる:

#!/usr/bin/env perl 

use strict; use warnings; 
use YAML; 

my %hash = qw(a 1 b 2 c 3 d 4 e 5); 

# find all keys with odd values 

print Dump lookup_keys_by_value(\%hash, sub { 
     return unless @_; 
     my $v = shift; 
     return $v % 2; 
    }, 
); 

sub lookup_keys_by_value { 
    my ($hash, $criterion) = @_; 

    my @keys; 

    while (my ($k, $v) = each %$hash) { 
     push @keys, $k if $criterion->($v); 
    } 

    return \@keys; 
} 
+1

これをより汎用的にするには、比較演算子( 'eq'、' == '、'> 'など)のそれぞれに対してsubを作成し、どちらが必要なのかに応じてコードrefを渡すことができます。 – simbabque

+0

ありがとう、私はこれが好きです。 – cstamas

1

あなたがあなたの検索機能に基準関数を渡すことができ、過負荷

use overload (
'>' => 'compareBigger', 
'<' => 'compareSmaller', 
'==' => 'equals' 
) 
2

ここで(おそらくあまりにも "賢い")考えだ。

use strict; 
use warnings; 

{ no strict 'refs'; 
    # When called like __PACKAGE__->$op(...), __PACKAGE__ is $_[0] 
    *{'>'} = sub { return $_[1] > $_[2]; }; 
    *{'<'} = sub { return $_[1] < $_[2]; }; 
    *{'=='} = sub { return $_[1] == $_[2]; }; 
} 

sub determine { 
    my ($first_arg, $op, $second_arg) 
     = map { s/^\s+//; s/\s+$//; $_ } 
      split(/\s*([<>]|==)\s*/, @_ == 1 ? shift : "@_") 
     ; 
    say "$first_arg $op $second_arg => " 
     . ( __PACKAGE__->$op($first_arg, $second_arg) ? 'TRUE' : 'FALSE') 
     ; 
} 

determine(qw(1 < 2)); 
determine(qw(2 < 1)); 
determine(qw(1 > 2)); 
determine(qw(2 > 1)); 
determine(qw(1 == 2)); 
determine(qw(1 == 1)); 
determine(qw(2 == 2)); 
determine(' 1 < 2 '); 
determine(' 2 < 1 '); 
determine(' 1 > 2 '); 
determine(' 2 > 1 '); 
determine(' 1 == 2 '); 
determine(' 1 == 1 '); 
determine(' 2 == 2 '); 
+0

それは賢いですが、本当に賢いかもしれません。 –

+1

@SinanÜnür、その理由が警告です。実際には、ハッシュではこれを越える利点はありませんが、シンボルテーブルに入っているときには、「演算子を渡す」ように感じるだけです。 :) – Axeman