Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Making a Hash of Arrays

by Limo (Scribe)
on Sep 22, 2000 at 22:38 UTC ( #33677=perlquestion: print w/replies, xml ) Need Help??

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

Can someone tell me what's wrong here?
sub processfile { my $script = "/export/home/limo/Perl/exfields.pl -e"; my ($file, $list) = @_; my %hash; my @list = (split /,/, $list); foreach my $arg(@list) { open(FILE, "$script $arg $file |") or die "System error: $!\n"; while (<FILE>) { chomp; # print "$_\n"; returns expected results my @array = split; # printing each array element also passes here $hash{$arg} = [@array]; push (@{ $hash{$arg} }, @array) unless /^\#|none|unkno/i; } } foreach my $keys( sort keys %hash) { print "@{ $hash{$keys} }\n"; # print statement here returns 1 "value "value" pair per key } close FILE; return %hash; }
Printing passes up until either the point where I populate the hash or try to print each key/value. What am I doing wrong here? FWIW, I am using Cookbook, recipe 11.2, pg. 372, for example.

Replies are listed 'Best First'.
RE: Making a Hash of Arrays
by chromatic (Archbishop) on Sep 22, 2000 at 22:55 UTC
    You're putting stuff in the anonymous array (potentially) twice:
    $hash{$arg} = [@array]; push (@{ $hash{$arg} }, @array) unless /^\#|none|unkno/i;
    The first line copies all of the contents of @array and populates an anonymous array with them, sticking it in the hash slot.

    The second pushes all of the elements of @array onto the anonymous array, unless your regex matches. (Which it probably won't.)

    I'd do something like:

    while (<FILE>) { next if /^#/; next if /none|unkno/i; chomp; # print "$_\n"; returns expected results my @array = split; # printing each array element also passes here $hash{$arg} = [@array]; }
      I just saw that! I was just getting ready to update my post. When I remove the line:
      $hash{$arg} = [@array];
      things seem better, although printing each key/value seems to print "value" as one continuous string.
RE: Making a Hash of Arrays
by Adam (Vicar) on Sep 22, 2000 at 22:57 UTC
    # Wouldn't $hash{$arg} = \@array; # be more desirable then $hash{$arg} = [@array];
    ???
      Depends on your desired result. The first line would allow you to manipulate @array by manipulating the array referenced by $hash{$arg}, thus $hash{$arg}->[0] = 0 changes $array[0]. The second method builds a reference using the values in @array. Thus, modifying the array referenced by $hash{$arg} modifies something totally independent of @array. Either way is perfectly legal/valid, but it depends on what you're wanting to actually do.
        That point is moot, since the array is lexically scoped (created via my()). So a reference to it would keep it around after it goes out of scope, so modifying it doesn't really pose a problem.

        Incidentally, there's a bit of optimization to be made in the program:
        sub processfile { my ($file, $list) = @_; my $script = "/export/home/limo/Perl/exfields.pl -e"; my %hash; # no need for @list for my $arg (split /,/ => $list) { open(FILE, "$script $arg $file |") or die "System error: $!\n"; while (<FILE>) { # did you mean /^(#|none|unkno)/ ? next if /^#|none|unkno/i; chomp; $hash{$arg} = [split]; # or, if there'll be another $arg of the same value.. # push @{ $hash{$arg} }, split; } close FILE; } # consider return a REFERENCE to the hash... # it might be more memory-effective return %hash; }
        If more description is needed than the comments provide, let me know.

        $_="goto+F.print+chop;\n=yhpaj";F1:eval

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2023-01-30 05:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?