in reply to Transform Array Ref to Hash Ref - Where's my error?

What you've got there is pretty close, but you've got the syntax for the push part a bit backwards. With push, you always specify the array to be pushed onto first, and you don't use the assignment operator:
my %hash; foreach my $ary ( @array ) { if ( !defined($$ary[1]) ) { $$ary[1] = '0' } push @{$hash{$$ary[1]}}, $$ary[0]; } print Dumper \%hash;
I also changed your @$ usage to $$. @$ary[1] is an array slice, which is not appropriate to use when you are only dealing with single elements, as is the case here. I also introduced the defined function, which is the only valid way to check whether a value is defined or not (string comparison to undef will succeed for the empty string '' and throw a warning).

By the way, as a personal preference I like to use -> for single element lookups in hash or array references because I think it is clearer. So everywhere you have $$ary[1] you can instead say $ary->[1].

Forgot one other thing. I changed print Dumper %hash to print Dumper \%hash because otherwise Dumper will treat your hash as simply a list of values and not as an actual hash.

Yet one more. I aligned the two statements inside the foreach loop because they are in fact part of the same block. In the OP a reader might think that push statement was part of the if block, which it's not.

Replies are listed 'Best First'.
Re^2: Transform Array Ref to Hash Ref - Where's my error?
by davidrw (Prior) on Feb 14, 2006 at 02:12 UTC
    No need (and probably shouldn't ... though i see that OP did) to modify the input w/the $$ary[1] = '0' statement ..
    my %hash; foreach my $row ( @array ) { my $k = defined($row->[1]) ? $row->[1] : 0; push @{ $hash{$k} }, $row->[0]; }
    or a more condensed version:
    my %hash; push @{ hash{ defined($_->[1]) ? $_->[1] : 0 } }, $_->[0] for @array;
      Even more condensed:
      my %h; push @{$h{$_->[1]||0}}, $_->[0] for @a;