Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Set condition only if array becomes empty

by Anonymous Monk
on Sep 26, 2017 at 12:50 UTC ( [id://1200107]=perlquestion: print w/replies, xml ) Need Help??

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

I need to execute "else" condition only if , foreach checks all the values of the array and array has become empty. I am using the following code (some commands are internal to the organization, but you can infer)

$rh->cmd('show pim join summary | except "^Instan +ce|^Route"'); my $output = $rh->get_response; my @outputlist = split /\s+/, $output; foreach $output (@outputlist) { if ($output eq "3000") { put_log("All PIM groups are learned in + Master"); } else { put_log ("fail"); } }

output of the above command "show pim join summary | except "^Instance|^Route" is below

regress@sherlock# run show pim join summary | except "^Instance|^Route +" (s,g) 3000 200

In the above code, foreach gets each member of the array and it finds 3000 in the middle and it passes, but i want the else condition to be executed only once , not for each array element comparison. More precisely, else should be excuted only after the array is empty and 3000 is not found. Is there a way to do it

Replies are listed 'Best First'.
Re: Set condition only if array becomes empty
by choroba (Cardinal) on Sep 26, 2017 at 12:57 UTC
    Either check the number of matching lines via grep
    if (grep '3000' eq $_, @outputlist) { # ... } else {
    or add a flag:
    my $seen; # ... if ($output eq '3000') { $seen = 1; # ... } put_log('fail') unless $seen;
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Set condition only if array becomes empty
by thanos1983 (Parson) on Sep 26, 2017 at 13:04 UTC

    Hello Anonymous Monk,

    Why don't you try to create a subroutine and apply return into two points. Sample test code below:

    use strict; use warnings; use Data::Dumper; use feature 'say'; my @array = qw( 1 2 3 ); my @secondary = qw ( 4 ); sub check { my ($arrayref) = @_; foreach my $element (@$arrayref){ say $element; return 'Found' if ($element eq 3); } return 'Not Found' } say check( \@array ); say check( \@secondary ); __END__ 1 2 3 Found 4 Not Found

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!

      thanos1983
      Nice solution, but I feel it would be beautiful if one's function has only one return, instead of two or more.
      Using a flag as choroba stated. something like thus:

      ... sub check { my $seen = 0; for my $el (@{shift(@_)}) { if ($el eq '3'){ # we only need the first occurrence $seen = 1; last; } } return $seen == 1? 'Found': 'Not Found'; # NOTE } ...

      If you tell me, I'll forget.
      If you show me, I'll remember.
      if you involve me, I'll understand.
      --- Author unknown to me
        Nice solution, but I feel it would be beautiful if one's function has only one return, instead of two or more.
        Why? I do not think it is wrong to have multiple exit points for a subroutine. Especially not in such a context.

        In the old times when Wirth, Dijkstra, and others were (rightly) trying to promote structured programming (against the spaghetti plates of goto's that were prevalent at the time), some over-zealous structured programming bigots insisted that all functions (and loops) should have only one entry point and one exit point. For the entry point, fair enough, that's what most modern programming languages offer anyway. But having multiple return statement is fairly legitimate: you look for a value (e.g. in an array, a file, etc?) and return it immediately when you find it, and return something else (undef, false value, failure message, etc.) if you traversed the whole array or read the whole file and did not find what you were looking for. There is nothing wrong with that.

        Just like having multiple next and last control statements in a loop is perfectly OK and often allows for more natural code than multiple flags.

        Using a flag and a last statement, as you're suggesting, is also an entirely legitimate way of doing it, but I do not think it is any better (or worse, for that matter) than thanos1983's solution. TIMTOWTDI.

        If I dare quoting my own book on Perl 6:

        ... the one-exit notion has led people to bend over backwards and write a lot of unnatural code. Much of programming consists of traversing decision trees. A decision tree naturally starts with a single trunk but ends with many leaves. Write your code with the number of loop controls (and subroutine exits) that is natural to the problem you’re trying to solve. If you’ve declared your variables with reasonable scopes, everything gets automatically cleaned up at the appropriate moment, no matter how you leave the block.
        A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Set condition only if array becomes empty
by virtualsue (Vicar) on Sep 27, 2017 at 09:23 UTC
    You already have valuable hints in this thread. Make sure you strip or check for a newline at the end of the lines that your 'cmd'or 'get_response' returns, unless they already do that. It's easy to forget this (I often do). Either
    chomp($output)
    or
    if ($output eq "3000\n")
    should work. If it doesn't, searching for newline removal here and on the web will come up with a lot of discussion about it. Some ways to check if an array is empty:
        if (! @array) {}
    
     
        if (scalar(@array) == 0) {}
    
    In the code you showed us, you might just check if $output is "" or whatever happens when you run $rh->get_response on a command that didn't provide any output. I also would be curious as to where the "3000" came from as it sounds like a magic number, but for all I know that's guaranteed to be fine for the entire lifetime of your script.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (5)
As of 2024-04-19 23:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found