Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

smartmatch with multiple search values

by toohoo (Beadle)
on Jul 16, 2019 at 13:55 UTC ( [id://11102922]=perlquestion: print w/replies, xml ) Need Help??

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

Hello all,

is there a way to search other than loop with smartmatch for multiple search values?

My code below

best regards

#!/usr/bin/perl use v5.10; use experimental 'smartmatch'; no warnings 'experimental::smartmatch'; $VAR1 = [ '11', '14' ]; my @owner_grouprights = @$VAR1; if ( '11' ~~ @owner_grouprights ) { print "test3\n"; } # the big deal -- if it only would work if ( {4|5|6|7|8|9|10|11|12} ~~ @owner_grouprights ) { print "test2\n"; } my $owner_grouprights = join( ' ', @owner_grouprights ); # with loop my $testarrorig = '4|5|6|7|8|9|10|11|12'; my @testarr = split( /\|/, $testarrorig ); my $testarr = join( ' ', @testarr ); foreach $tst ( @testarr ) { given( $tst ) { when ( @owner_grouprights ) { print "$_ hit!\n"; } default { #print "$_ miss\n"; } } }

Replies are listed 'Best First'.
Re: smartmatch with multiple search values
by hippo (Bishop) on Jul 16, 2019 at 14:09 UTC

    Do you mean this?

    #!/usr/bin/env perl use strict; use warnings; my @owner_grouprights = ('11', '14'); my @matches = grep { /4|5|6|7|8|9|10|11|12/ } @owner_grouprights; if (@matches) { print "test2"; }

    Use "smartmatch" at your peril.

      Hello Hippo

      that's a good idea. Thank you.

      regards

Re: smartmatch with multiple search values
by daxim (Curate) on Jul 16, 2019 at 18:35 UTC

      Hello Daxim

      thanks so far.

      Can't locate object method "new" via package "Set::Scalar" (perhaps you forgot to load "Set::Scalar"?)

      I have a restricted Perl environment here and can not install packages.

      but thanks and regards

        can not install packages
        Just fatpack the module.
Re: smartmatch with multiple search values
by haukex (Archbishop) on Jul 16, 2019 at 14:56 UTC
Re: smartmatch with multiple search values
by dsheroh (Monsignor) on Jul 17, 2019 at 07:27 UTC
    Looks to me like you aren't really that interested in the order of the values in @owner_grouprights and instead just want to be able to easily check whether specific values are present or not. This is not a job for an array. You want a hash:
    #!/usr/bin/env perl use strict; use warnings; use 5.010; # Don't really need the qw, since these are numbers, but the original # code explicitly made them strings, so whatever. my @owner_grouprights = qw( 11 14 ); my %rights_hash; $rights_hash{$_}++ for @owner_grouprights; if (exists $rights_hash{11}) { say "test3"; } for (4 .. 12) { if (exists $rights_hash{$_}) { say "test2"; last; # avoid duplicate messages if more than one is present } } # Or, alternately: if (grep /4|5|6|7|8|9|10|11|12/, keys %rights_hash) { say "test2 alt"; } # Note, though, that the two alternatives are not equivalent. The # first (if exists) only returns exact matches, while the second # (grep) also finds substring matches. So, e.g., 114 would match the # 'grep' version, but not the 'if exists' version. Adding begin/ # end-of-string anchors (^/$ or \A/\Z) to the 'grep' version's regex # will disallow partial matches if you want that, but don't want the # explicit 'for' loop. my $owner_grouprights = join( ' ', sort keys %rights_hash); my @testarr = (4 .. 12); for my $tst (@testarr) { if (exists $rights_hash{$tst}) { say "$tst hit!"; } else { say "$tst miss"; } }

      Hello @dsheroh,

      thank you very much. It seems the hash solution is the most best one can use in my case.

      Thanks and have a nice day.

Re: smartmatch with multiple search values
by Marshall (Canon) on Jul 17, 2019 at 06:52 UTC
    I am unsure about what you intend. Some code below.
    I highly recommend against using experimental features except for "fun code".
    #!/usr/bin/perl use strict; use warnings; my $VAR1 = [ '11', '14' ]; #create a hash... my %owner_grouprights = map{$_=>1}@$VAR1; if ($owner_grouprights{'11'}) { print "test3-> 11 exists as a groupright\n"; } # you say: "the big deal -- if it only would work" WHAT?? ### what do you expect??? if (grep{/4|5|6|7|8|9|10|11|12/} keys (%owner_grouprights)) { print "test2->some number exists as a groupright\n"; #11 exists } # with loop my $testarrorig = '4|5|6|7|8|9|10|11|12'; my @testarr = split( /\|/, $testarrorig ); foreach my $tst ( @testarr ) { if (exists $owner_grouprights{$tst}) { print "$tst hit!\n"; } } __END__ test3-> 11 exists as a groupright test2->some number exists as a groupright 11 hit!
    Update: I am very circumspect about smart match. Sometimes this critter is too smart! And produces unexpected results. I don't see the need for it in the above code.

      Hello marshall,

      thanks for the hints, there are some real good points.

      One is you did the same thing with the match, same as Hippo above. Thanks

      A very good hint is the one with the hash. Thanks.

      The last one again is a loop. Some say this is not elegant ... But it works so far.

      Thanks for all, regards.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11102922]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (4)
As of 2024-04-16 06:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found