Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

terrible code about array matching...

by Discipulus (Canon)
on Nov 06, 2002 at 07:12 UTC ( [id://210675]=perlquestion: print w/replies, xml ) Need Help??

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

hello Momks!

I'm still newbing around perl coding, suggest me something about the following problem and dont let me publish my neanderthal code..
SITUATION:I have a sub that return an array.The user put some parameters in @ARGV.
GOAL:I want verify that all argv input match with the first array before print it(but only if ALL match).

My first attempt was to give a big argoument to a if cicle but it was a flop.can I put a foreach cicle into a if condition?
My neanderthal code runs but it is terrible to my newbies eyes too.. plz suggestion..
foreach $aa (@ARGV) { if ($aa=~/^peace$/) {$cond[0]='peace'; push(@numeri,0 )} elsif ($aa=~/^child$/){$cond[1]='child'; push(@numeri,1 )} elsif ($aa=~/^free$/) {$cond[2]='free'; push(@numeri, 2)} elsif ($aa=~/^love$/) {$cond[3]='love'; push(@numeri, 3)} elsif ($aa=~/^enjoy$/) {$cond[4]='enjoy'; push(@numeri, 4)} else {print "\n\n$aa wrong argoument!!! I proceed with @cond\n\n"} } #the possible returned array from a sub @car=qw(peace child free love enjoy); print "\n\ncar=@car\ncond=@cond\nnums=@numeri\n\n\n"; ##############here suggestion please################### $bol=1; foreach $num(@numeri) { last if ($bol==undef); if ($car[$num]eq$cond[$num]){$bol=1}else{$bol=undef} } if (defined $bol){print"boleano=$bol FOUND!"} else{print "NOT found!"}
greetings freom sunny roma
lor*

Replies are listed 'Best First'.
Re: terrible code about array matching...
by chromatic (Archbishop) on Nov 06, 2002 at 07:19 UTC
Re: terrible code about array matching...
by grantm (Parson) on Nov 06, 2002 at 07:43 UTC

    You could simply say:

    if(join(',', @car) eq join(',', @cond)) { print "FOUND\n"; } else { print "NOT FOUND\n"; }

    Also, instead of saying:

    if ($aa=~/^peace$/)

    It would be more efficient to say:

    if ($aa eq 'peace')

    Please clarify what you're try to do if this doesn't help.

      That's a bit dangerous isn't it?

      #!/usr/bin/perl use strict; use warnings; my @car = ('a', 'b,c'); my @cond = ('a', 'b', 'c'); if(join(',', @car) eq join(',', @cond)) { print "FOUND\n"; } else { print "NOT FOUND\n"; }

      This indicates that the arrays are the same even tho', clearly, they aren't.

      If you're going to use code like this you have to know what are valid characters in your input arrays and be very careful in choosing your join string.

      --
      <http://www.dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

        That's a bit dangerous isn't it?

        In general yes, it is dangerous and as you suggest it's important to chose a separator that you knew could not occur in the data.

        In the specific case of my suggestion, (which possibly wasn't clear) I was assuming the arrays had been populated by the original posters' code which validated each argument before pushing onto the array. I was merely proposing to replace the loop which compared the arrays.

        The other problem with my code as a general solution is that it doesn't scale well. Once again though, in the context of what the poster was trying to do I think it's reasonable.

      ok maybe i have english level difficulties.. ;)
      thnks for the remark about matching vs eq
      foreach $aa (@ARGV) { if ($aa eq 'peace'){$cond[0]='peace'; push(@numeri,0 )} elsif ($aa eq 'child'){$cond[1]='child'; push(@numeri,1 )} elsif ($aa eq 'free') {$cond[2]='free'; push(@numeri, 2)} elsif ($aa eq 'love') {$cond[3]='love'; push(@numeri, 3)} elsif ($aa eq) {$cond[4]='enjoy'; push(@numeri, 4)} else {print "\n\n$aa wrong argoument!!! I proceed with @cond\n\n"} } #the possible returned arrays from a sub @car=qw(peace child free love enjoy); #1 #or @car=qw(war child -- love enjoy); #2 #or @car=qw(peace song freedom -- xx); #3 ##############here suggestion please################### $bol=1; foreach $num(@numeri) { last if ($bol==undef); if ($car[$num]eq$cond[$num]){$bol=1}else{$bol=undef} } if (defined $bol){print"boleano=$bol FOUND!"} else{print "NOT found!"}
      Example of what I wont:
      you put as INPUT: peace
      ok for the first @car
      wrong for the second
      ok for the third

      you put as INPUT: peace love
      ok for the first occuourence of @car
      wrong for the second and third occourence

      In this way,when I receive 5 times @car, I want print it ONLY if all the option insered in @argv match with the courrent array.
      many thanks
      lor*
Re: terrible code about array matching...
by fruiture (Curate) on Nov 06, 2002 at 14:14 UTC
    # this is what your first loop does: # it checks the input and brings it into a certain order sub filter_by_array { my ($data,$filter) @_; my $valid = join '|', map quotemeta, @$filter; $valid = qr/$valid/; my %position = do { my $i=0; map {($_=>$i++)} @$filter } my @result = (); foreach( @$data ){ $result->[ $position{ $_ } ] = $_ if /$valid/ } @result } # this is your second piece of code # it checks if the second array completely equals # the corresponding leading elements of the first # array. sub array_pattern { my ($l,$r) = @_; @$l >= @$r or return; for( 0.. @$r-q ){ $l->[$_] eq $r->[$_] or return; } } # validate the input into a certain order my @validated = filter_by_array( \@ARGV , [qw(peace child free love enjoy)] ); # the data you get from somehwere my @car = from_wherever_youlike(); # verify that @car at has all elements of @validated # at its beginning print array_pattern( \@car , \@validated ) ? 'FOUND!' : 'NOT found!' , "\n";

    I'm all the time wondering: what do you need this for. It doesn't make much sense (to me).

    --
    http://fruiture.de
Re: terrible code about array matching...
by jlongino (Parson) on Nov 06, 2002 at 15:38 UTC
    I'm not exactly sure what you're trying to do but if you're only trying to validate parameters, something like the following would work:
    use strict; use warnings; my %valid = ( peace => 0, child => 1, free => 2, love => 3, enjoy => 4 ); my @test = qw(freely enjoy love); my @parms; for my $test (@test) { if (exists $valid{$test}) { push (@parms, $test); } else { print "\n\nSkipping bad argument '$test'!!!\n\n"; } } print "\n\nValid parms:\n"; print " ", pack('A8',$_), ": position: $valid{$_}\n" for @parms;
    Update: After rereading a few times, I realize that the poster needs what chromatic suggested. /me finishes coffee before responding to anymore posts.

    --Jim

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (3)
As of 2024-04-16 23:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found