Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

error message in the end of the array looping?

by Anonymous Monk
on May 29, 2006 at 20:43 UTC ( #552350=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello!
I have an array which I read each element at a time.
Then I use the array's element as a key for a hash I have created.
If the value of the hash for the given key is correct, I stop reading the array, using 'last'.
If the value is wrong, I keep reading, using 'next'.
What I want to ask is how and where shall I place an error message that will say for example "We read the entire loop and found no matches" ? I guess I must put it somewhere after the next statements?
Imagine that I have something similar to :
foreach $a(@array) { if ($hash{$a}="correct_value") {print "Success"; last;} else {next;} }
Any hints? Thank you in advance!

Comment on error message in the end of the array looping?
Download Code
Re: error message in the end of the array looping?
by Anonymous Monk on May 29, 2006 at 20:55 UTC

    that next is useless, as long as you don't last, the loop is going to continue until it reaches the last element of the array.

        Then why hide behind the anon monk?
Re: error message in the end of the array looping?
by Zaxo (Archbishop) on May 29, 2006 at 20:55 UTC

    You need the string equality op, 'eq', not assignment, '='. You can keep track of how many matches you have by incrementing a variable in the true branch. As it's written, the else branch is unnecessary; control goes to the next iteration anyway.

    my $counter; for (@array) { if ($hash{$_} eq "correct_value") { $counter++ print "$_ Success\n"; last; } } print 'We have a match.', $/ if $counter;

    Update: Albannach++ quickly spotted an error, repaired.

    After Compline,
    Zaxo

      This surely popped somewhere else here in PM (I kinda remember something), but I did a supersearch for $/ without finding anything applicable. Why:
      print 'We have a match.', $/
      instead of
      print "We have a match.\n"
      (apart from TIMTOWTDI)? Pointers welcome!

      Flavio
      perl -ple'$_=reverse' <<<ti.xittelop@oivalf

      Don't fool yourself.

        Force of habit, mainly. I usually prefer giving print a list to concatenating strings and variables first. The habit just carries over to control characters like this, too.

        I used to believe that $/ had some advantage over "\n" in platform independence, but I'm over that now.

        After Compline,
        Zaxo

Re: error message in the end of the array looping?
by GrandFather (Cardinal) on May 29, 2006 at 21:12 UTC

    A good answer needs a little more context. For example, if the loop is in a sub then you can return rather than last when you get and have dealt with the match:

    # always use strictures (the following two lines) use strict; use warnings; my @array = qw(key1 key2 key3 key4); my %hash = (key2 => undef, key4 => 'The goods', key5 => 'More goods'); doLoop (); sub doLoop { for my $key (@array) { next if ! exists $hash{$key}; # Skip if the key is not used in + the hash next if ! defined $hash{$key}; # Skip if the key exists, but i +s undefined next if $hash{$key} ne 'No goods'; print "The value for '$key' is '$hash{$key}'\n"; return; } print "Failed to find matching key\n" }

    Prints:

    Failed to find matching key

    Without the sub, or if there is more work to do following the loop, you need to keep note of match success. Something like:

    use strict; use warnings; my @array = qw(key1 key2 key3 key4); my %hash = (key2 => undef, key4 => 'The goods', key5 => 'More goods'); my $match = 0; for my $key (@array) { next if ! exists $hash{$key}; # Skip if the key is not used in the + hash next if ! defined $hash{$key}; # Skip if the key exists, but is un +defined next if $hash{$key} ne 'No goods'; print "The value for '$key' is '$hash{$key}'\n"; $match = 1; last; } print "Failed to find matching key\n" if ! $match;

    DWIM is Perl's answer to Gödel
      In the past, I've encountered warnings from perl about exiting a loop via return and expected your first example to generate one. However, when I tested it (even after modifying key2's undef to "No goods" to get a successful match), the example code produced no such warning. So now I'm confused...

      Any idea why this example code doesn't emit a warning about exiting the loop via return? (Unfortunately, I've long since fixed my code to remove that warning and don't recall the details clearly enough to provide an example which produces it.)

        If you try to return when not in a sub you get:

        use strict; use warnings; return 10;

        Prints:

        Can't return outside a subroutine at noname2.pl line 4.

        DWIM is Perl's answer to Gödel
Re: error message in the end of the array looping?
by isotope (Chaplain) on May 30, 2006 at 02:15 UTC
    See:
    FIND_MATCH: { foreach my $a (@array) { if( $hash{$a} eq 'correct_value' ) { print 'Success'; last FIND_MATCH; } } warn "Didn't find a suitable match!"; }

    By targeting the last at the outer block, if you find a match, you completely exit that block. Otherwise, if you make it all the way through the foreach loop without a match, you will hit the warning message right before exiting the block.


    --isotope
Re: error message in the end of the array looping?
by codeacrobat (Chaplain) on May 30, 2006 at 06:11 UTC
    If @array is not too long, then you can use the following:
    @matches = grep {$hash{$_} eq "correct_value"} @array; if (@matches){ print "Success" } else { warn "no match" }
Re: error message in the end of the array looping?
by qbxk (Friar) on May 30, 2006 at 17:54 UTC
    o anonymous brother, I feel that i must bring a certain unsaid morsel of advice to the forefront, for in your particular case it seems exceedingly relevant. it is the case of your indentation and whitespace style. the replies here contain many good examples of effectively using whitespace. specifically, i strongly disagree with your choice of
    if ($condition) {foo(); bar();}
    among the many reasons for my distaste, one, is because there is no room to "grow". this is not easily maintainable. something more like
    if ( $condition ) { foo(); #easily read and/or insert & modify code here bar(); }
    is my typical method

    i know this is a sensitive subject, and all are entitled to their own approach, but some constructs are more widely used because they offer advantages to the programmer(s). in the possible case that you have not puch much thought into your use of whitespace and the other superficial aspects of your code* i suggest that you do. it can clear your mind, it may cleanse your soul.

    *some superficial aspects of code that come to mind:
    variable naming, comments, commonly used task idioms, choice of quote characters

    It's not what you look like, when you're doin' what you’re doin'.
    It's what you’re doin' when you’re doin' what you look like you’re doin'!
         - Charles Wright & the Watts 103rd Street Rhythm Band
Re: error message in the end of the array looping?
by jayanthsv (Initiate) on May 31, 2006 at 06:14 UTC
    If all you want to do is check if there was atleast one match in the hash value, then you can do as follows...
    if ($hash{$a} = "correct_value") { print "Success"; $flag = 1; last; }
    At the end of "for" loop, check if $flag==1. If not, you have an error.
Re: error message in the end of the array looping?
by ioannis (Priest) on May 31, 2006 at 09:19 UTC
    Use the first() function from List:Util .

    print +(first { $_ eq 'correct_value' } @arr) || 'not found';

      Alternatively, if you can get your hands on it, List::MoreUtils has a bunch of small, but useful subroutines.
      -----------------------------

      use List::MoreUtils qw(any); ... print "Success" if any { $_ eq "correct_value" } @hash{@array};

      -----------------------------
      Notes:
      1 - note the use of a hash slice; it takes some getting used to, having a @ instead of a % in front.
      2 - please use something more meaningful than %hash or @array as var names in your actual code :)

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (8)
As of 2014-12-18 04:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (41 votes), past polls