Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

What's the best way to perform matches with out using lots of IF statements ?

I would also like users to be able to perform multiple searches for example:
(($type eq @split_sp_data2) && ($line eq @split_sp_data4))

The below variables are coming from a form and @split_sp_data is the array that contains all the data. There must be a better way, can anyone show me the light ?

if ($net eq @split_sp_data[1]) { #display results } elsif ($type eq @split_sp_data[2]) { #display results } elsif ($user eq @split_sp_data[3]) { #display results } elsif (@split_sp_data[$min] > 0) { #display results } elsif ($line eq @split_sp_data[4]) { #display results } elsif ($contract eq @split_sp_data[9]) { #display results }
Thanks

Code tags added by GrandFather

Replies are listed 'Best First'.
Re: Better way of matching
by izut (Chaplain) on Mar 08, 2006 at 18:36 UTC
    First, use the code tag. Now answering your question, you can use hashes for that (untested):
    my %functions = ( net => sub { ... }; type => sub { ... }; ); my %input_values = (net => 1, type => 2); my %cmp_values = (net => 1, type => 3); my @keys = qw/net type/; foreach my $key (@keys) { my $curval = $input_values{$key}; if ($curval == $cmp_values{$key}) { &{$functions{$key}}($curval); } }

    Igor 'izut' Sutton
    your code, your rules.

Re: Better way of matching
by GrandFather (Saint) on Mar 08, 2006 at 18:33 UTC

    Do you use the same display code in each case, or is the code dependent on the specific match?

    Are the test strings constant or can they vary over time?

    Is the order that the tests are made actually important and do you require that only one set of results is shown?


    DWIM is Perl's answer to Gödel
Re: Better way of matching
by kirbyk (Friar) on Mar 08, 2006 at 19:14 UTC
    Another, more general case method, is to use the ? operator:
    ($net eq $x) ? 1 : 0; is the same as if ($net eq $x) { return 1; } else { return 0; }
    The nice thing is that you can cascade them to make readable tableish structures:
    ($x eq $y) ? _do_something() : ($x eq $z) ? _do_something_else() : ($x eq $w) ? _do_a_third_thing() : _do_default_thing;

    -- Kirby, WhitePages.com

Re: Better way of matching
by pKai (Priest) on Mar 08, 2006 at 21:35 UTC

    Seems more like a matter of taste to me, whether you prefer a hash of subs or the ternary operator to your original elsif cascade.

    OTOH using warnings with your code, perl would comment on your using one-element hash slices instead of array element references.

    Also the OP could use another pair of <code> tags, since the links to node 2 and 4 are interesting, but somewhat OT. ;-)

Re: Better way of matching
by chargrill (Parson) on Mar 09, 2006 at 13:47 UTC

    You may wish to be a little more careful, @split_sp_data[1] probably doesn't match what you want it to, while $split_sp_data[1] probably will.



    --chargrill
    $,=42;for(34,0,-3,9,-11,11,-17,7,-5){$*.=pack'c'=>$,+=$_}for(reverse s +plit//=>$* ){$%++?$ %%2?push@C,$_,$":push@c,$_,$":(push@C,$_,$")&&push@c,$"}$C[$# +C]=$/;($#C >$#c)?($ c=\@C)&&($ C=\@c):($ c=\@c)&&($C=\@C);$%=$|;for(@$c){print$_^ +$$C[$%++]}