in reply to Trouble grepping values when hash contains multiple values per key

my @date = grep /$date/,@{$countries${cntry_of_issue}})
That code doesn't even compile. Try this instead:
my @dates = grep /$date/, @{ $countries{$cntry_of_issue} };

I got rid of the unmatched right paren, added a semicolon, and moved the dollar sign to the right of the curly bracket to form the scalar variable $cntry_of_issue, rather than the bareword cntry_of_issue.

Here is a self-contained example which seems to work for me:

use warnings; use strict; use Data::Dumper; my %countries; while (<DATA>) { chomp; next if /^\s*$/ || /^\#/; my $aref = [split /,/, $_]; push( @{$countries{$aref->[2]}}, $aref->[5]); } my $date = 20100101; my $cntry_of_issue = 'CH'; my @dates = grep /$date/, @{ $countries{$cntry_of_issue} }; print Dumper(\@dates); __DATA__ 978,XBRN,CH,Berne Stock Exchange,2010,20100101 978,XBRN,CH,Berne Stock Exchange,2010,20100102 978,XBRN,CH,Berne Stock Exchange,2010,20100321 978,XBRN,CH,Berne Stock Exchange,2010,20100324
Prints:
$VAR1 = [ '20100101' ];

Replies are listed 'Best First'.
Re^2: Trouble grepping values when hash contains multiple values per key
by dirtdog (Monk) on Jun 05, 2010 at 16:55 UTC

    Thanks Toolic

    When i pasted the code in, some of the syntax got messed up, specifically the curly braces, but i did have the same syntax that you had

    I ran what you had and it did work beautifully

    ultimately, i'm trying to get the following piece of code to work. Basically, I have my date and i check it against the calendar file to see if the date is a holiday...if it does exist it means it's a holiday so i increment the date by 1 day (unless it's a sat or sun..then i increment it until it's not sat or sun..this piece of logic works), then i check the newly incremented date against the holiday file again. I repeat this until it doesn't exist in the holiday file. Then i know i have a date that's not a holiday.

    The following code for some reason is not working for me. It's hitting the until loop but not entering it even if the newly incremented date is also a date in the holiday file

    You may need to mock up the holiday config file with back to back holiday's to create the scenario

    $date='20100101'; $new_date=get_next_bus_day($date);
    until (my @date = grep !/$new_date/,@{$countries${cntry_of_issue}}) { $new_date=get_next_bus_day($new_date); }
    sub get_next_bus_day { my $inc=1; my $inc4sat=2; my $inc4fri=3; my $new_date; my $date=shift; DEBUG > 1 and print "date is: >$date<\n"; my $y = substr($date,0,4); my $m = substr($date,4,2); my $d = substr($date,6,2); my $time = timelocal("", "", "", $d, $m-1, $y); if ((localtime($time))[6] == 5) { $new_date=strftime "%Y%m%d", localtime timelocal(0,0,0,$d,$m-1,$y) + +($inc4fri * 24 * 60 * 60); } elsif ((localtime($time))[6] == 6) { $new_date=strftime "%Y%m%d", localtime timelocal(0,0,0,$d,$m-1,$y) + +($inc4sat * 24 * 60 * 60); } else { $new_date=strftime "%Y%m%d", localtime timelocal(0,0,0,$d,$m-1,$y) + +($inc * 24 * 60 * 60); } return $new_date; }

    Do you see any obvious reason why this wouldn't work?

Re^2: Trouble grepping values when hash contains multiple values per key
by dirtdog (Monk) on Jun 05, 2010 at 17:31 UTC

    I see the problem now

    I'm expecting grep to return true or false, but since this is a list context it will return the actual values. Is there any way to force grep to evaluate these in a scalar context in order to return a "true" or "false" in this case?

      Is there any way to force grep to evaluate these in a scalar context in order to return a "true" or "false" in this case?

      Yes, evaluate grep in scalar context. It's that easy!

      my $found_any = grep { ... } @whatever;

      Boolean context is also a scalar context.

        my $found_any = grep { ... } @whatever;
        Because grep always iterates through the entire list, to stop on the first one found, you might try instead:
        use List::MoreUtils qw(any); my $found_any = any { ... } @whatever;
        or:
        use List::Util qw(first); my $found_any = defined first { ... } @whatever;
        ...though, in practice, it is unlikely to matter, performance-wise, unless @whatever is huge.

        As an aside, note that both any and first are built in to Perl 6.

      Is there any way to force grep to evaluate these in a scalar context in order to return a "true" or "false" in this case?
      Something like:
      my @date = grep ... if (@date) { ... }

      I just changed the until loop to a while loop and now it's working as expected

      Sorry for wasting your time...I was not thinking clearly

      while (my @date = grep /$new_ex_date/,@{$countries{$cntry_of_issue}}) { $new_date=get_next_bus_day($new_date); }