in reply to dealing with arrays as hash values

You're not that far off, I think your code would work if you replaced line 8 with $wo_usr_proj{$project} = \@usr_list; - hash values must be scalars, so a reference is needed.

Your code can be cleaned up a bit. You can read data directly from the file, for (<INFH>) { Loop variables are better as lexicals, and split uses $_ as the default second argument,     my ($user, undef, $project) = split /\|/; The remainder can be condensed to a conditional push onto the dereferenced array in the hash,

push @{$wo_usr_proj{$project}}, $user if $uo_hash{lc($user)} =~ /WO/; }

After Compline,
Zaxo

Replies are listed 'Best First'.
Re: Re: dealing with arrays as hash values
by goonarific (Initiate) on May 17, 2004 at 21:01 UTC
    Thanks, your comments for cleaning up my code helped a lot. I switched over that entire three lines , 6-8, to
    push @{$wo_usr_proj{$project}}, $user;
    I had some other stuff in that if statement that needed to be done too. but now when I print out the values from %wo_usr_proj, I only get array memory addresses:
    foreach $proj(sort(keys(%wo_usr_proj))) { print RHANDLE "$proj:\n"; foreach $element(sort($wo_usr_proj{$proj})) { print RHANDLE "$element\n"; } print RHANDLE "\n\n"; }
    That gave me the array memory adresses as output into my file I then tried:
    foreach $proj(sort(keys(%wo_usr_proj))) { print RHANDLE "$proj:\n"; foreach $element(sort($wo_usr_proj{$proj})) { print RHANDLE \$element; print RHANDLE "\n"; } print RHANDLE "\n\n"; }
    thinking that by derefencing $element it would give me the value, but instead it gave me scaler memory adresses. I don't think that the user names are actually getting put into the hash. Is there some initialization that needs to occur to "tell" the hash that its value is an array? I think if I get past this last part I'll be done. Thank you in advance for any help or comments on my code.
      In your first code above, $wo_usr_proj{$proj} is a reference to an array, not an array. You need to dereference this value, as you did in your call to push:
      push @{$wo_usr_proj{$project}}, $user;
      Currently the sort call is only sorting a list with one value (the address of the array stored in $wo_usr_proj{$proj}). The code below corrects this by dereferencing the hash element to retrieve the array:
      foreach $proj(sort(keys(%wo_usr_proj))) { print RHANDLE "$proj:\n";$wo_usr_proj{$proj} # note dereference: @{ $array_ref_here } foreach $element(sort @{ $wo_usr_proj{$proj} }) { print RHANDLE "$element\n"; } print RHANDLE "\n\n"; }
      Please take a look at Data::Dumper, as it is invaluable in illustrating the structure of the data in your code. You simply pass the Dumper function a reference to the data structure you wish to see expanded:
      use Data::Dumper; print Dumper \%wo_usr_proj; __END__ $VAR1 = { 'project2' => [ 'WO', 'WO2 ], 'project1' => [ 'WO' ] };
      As for your second code snippet, the code is not dereferencing $element, but rather, is creating another reference to $element.

      If $scalar is a reference to a scalar value, dereference using $$scalar:
      my $foo= "bar"; my $ref= \$foo; print $$ref; __END__ bar
      If $arr is a reference to an array, dereference using @$arr:
      my @array= qw(foo bar baz); my $ref= \@array; print join ':' => @$ref; __END__ foo:bar:baz
      If $href is a reference to a hash, dereference using %href:
      my %h= ( foo => 'bar' ); my $ref= \%h; while( my( $k, $v )= each %$ref ) { print "$k -> $v" } __END__ foo -> bar
      Please see the pod for perlreftut, perldsc, and perllol for more details.

      --sacked