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

Not sure what I'm doing wrong here. I've used grep many times looking for text within an array. For example,
@tmp = grep /${text}/,@array_of_something
So I decide to create a hash of arrays. The individual elements I can "see" -- for example, $tbl{"key"}[0] is correct. So can't I grep thru this too? See code below.
perl -de ' foreach $i (map {glob} "COMFILE1.2008*") { open(IN,$i); chomp(@tmp = (<IN>)); $tbl{$i} = [ @tmp ] ; close(IN); } open(IN,"dw_renewals.txt"); while(<IN>) { chomp; foreach $i (sort keys %tbl) { @tmp = [ @tbl{$i} ]; if (grep /$_/, [ @tbl{$i} ] ) { print "$_ in $i $y\n"; } } } '

Replies are listed 'Best First'.
Re: greping thru a hash of arrays
by pc88mxer (Vicar) on May 20, 2008 at 20:58 UTC
    You can grep through it, but you have an error in how you are accessing the array ref. You need to do it like this:
    if (grep /$_/, @{$tbl{$i}} ) {
    Update: Removed square brackets which I didn't see the first time around.

    Another problem, though, is that $_ gets assigned to in the grep operation, and that the match operator implicitly operates on $_. Thus, grep /$_/, ... is equivalent to grep { $_ =~ /$_/ } (...) which is probably not what you want. Instead, try this:

    while (my $line = <IN>) { ... for my $i (...) { if (grep /$line/, @{$tbl{$i}}) { ... } } }
      Thanks, that works. But why?
        grep /$_/, [ @{$tbl{$i}} ]

        means:
        Dereference the array-Ref in $tbl{$i}, make a reference to an anonymous array ( [ ] ) from the resulting list and grep through a list with a single item: the single reference to the anonymous array.

        @tbl{$i} is btw. wrong, see this example :
        $perl perl use strict; use warnings; my %hash; $hash{a} = [ 1,2 ]; print "@hash{a}", $/; Scalar value @hash{a} better written as $hash{a} at - line 7.

        edit: several updates/corrections due to some misleading thoughts while typing too fast

        There were a few errors. As linuxer pointed out, the second argument to grep should not be an array-ref. The second through last arguments are the list of items to grep through.

        Also, instead of @tbl{$i} you want to use @{$tbl{$i}}.

Re: greping thru a hash of arrays
by johngg (Canon) on May 20, 2008 at 22:16 UTC
    foreach $i (map {glob} "COMFILE1.2008*")

    You don't need to wrap a map around your glob.

    $ ls copy1 copy2 file1 file2 file3 $ perl -le 'foreach $i ( glob q{c*} ) { print $i }' copy1 copy2 $

    Cheers,

    JohnGG