Re: Dereferencing a Hash of Arrays
by philipbailey (Curate) on Jun 14, 2011 at 07:19 UTC
|
Your problem is that the values in hashes can only be scalars in Perl. However references are scalars, so you can use references to arrays:
my %alphabet = (
a => \@atags,
b => \@btags,
);
say for values %alphabet;
| [reply] [d/l] |
|
| [reply] [d/l] [select] |
Re: Dereferencing a Hash of Arrays
by jwkrahn (Abbot) on Jun 14, 2011 at 07:29 UTC
|
You have two problems:
my %alphabet = \(
'a' => @atags,
'b' => @btags,
);
You are using a list reference which produces a list of references, so your hash is the same as:
my %alphabet = (
\'a' => \@atags,
\'b' => \@btags,
);
say for @{values %alphabet};
The construct @{} dereferences an array reference but values %alphabet does not return an array reference, it returns a list.
| [reply] [d/l] [select] |
|
my @atags = qw( 1 2 3 4 );
my @btags = qw( 9 8 7 6 );
my %alphabet = (
'a' => \@atags,
'b' => \@btags,
);
say for values %alphabet;
output:
ARRAY(0x8376dd8)
ARRAY(0x837f298)
UPDATE: I did say for values %alphabet in response to an earlier version of Re^1 without the @{...}. My original code was my %alphabet = ('a', \@atags, 'b', \@btags); say for @{values %alphabet}; which prints an error similar to the OP. | [reply] [d/l] [select] |
|
knoppix@Microknoppix:~$ perl -MData::Dumper -Mstrict -wE '
> my @aTags = ( 1 .. 4 );
> my @bTags = reverse 6 .. 9;
> my %alpha = ( a => \ @aTags, b => \ @bTags );
> print Data::Dumper->Dumpxs( [ \ %alpha ], [ qw{ *alpha } ] );
> say q{-} x 20;
> say qq{@{ $_ }} for values %alpha;
> say q{-} x 20;
> say qq{@{ $alpha{ $_ } }} for keys %alpha;
> say q{-} x 20;
> foreach my $arrayRef ( values %alpha )
> {
> say for @{ $arrayRef };
> say q{-} x 20;
> }
> foreach my $key ( keys %alpha )
> {
> say for @{ $alpha{ $key } };
> say q{-} x 20;
> }'
%alpha = (
'a' => [
1,
2,
3,
4
],
'b' => [
9,
8,
7,
6
]
);
--------------------
1 2 3 4
9 8 7 6
--------------------
1 2 3 4
9 8 7 6
--------------------
1
2
3
4
--------------------
9
8
7
6
--------------------
1
2
3
4
--------------------
9
8
7
6
--------------------
knoppix@Microknoppix:~$
I hope this is helpful.
Update: Expanded the example code to show how to print one element per line as the OP's code seemed to want.
| [reply] [d/l] [select] |
Re: Dereferencing a Hash of Arrays
by Eliya (Vicar) on Jun 14, 2011 at 07:15 UTC
|
values returns two individual array references, which you can't dereference in one go. You have to iterate over them:
for my $aref (values %alphabet) {
say for @$aref;
}
Also, you probably meant to take references of the arrays only, not of every element used to initialize the hash. \( ... ) takes references of every element of the (unflattened!) list, so the resulting data structure is
...
use Data::Dumper;
print Dumper \%alphabet;
$VAR1 = {
'SCALAR(0x783790)' => [
'1',
'2',
'3',
'4'
],
'SCALAR(0x783e50)' => [
'9',
'8',
'7',
'6'
]
};
which is probably not what you intended. (The scalar refs are stringified here, because hash keys are always strings in Perl.) | [reply] [d/l] [select] |
|
my @idontgetit = values %alphabet;
say for @idontgetit->[0]->[0];
(It doesn't "work" in the sense of printing out what's desired but it does print out part of what's desired.) | [reply] [d/l] |
|
@idontgetit holds the two array refs. @idontgetit->[0] indexes the first one of it, and the second ->[0] indexes the first element of the (inner) array.
BTW, @idontgetit->[0]->[0] should better be written as $idontgetit[0]->[0] (turn on warnings, and Perl will tell you why).
| [reply] [d/l] [select] |
|
Re: Dereferencing a Hash of Arrays
by chromatic (Archbishop) on Jun 14, 2011 at 07:23 UTC
|
The reference operator here is a mistake, but it saves you a worse error:
my %alphabet = \(
You need to take references to both arrays in the list used to initialize the hash without taking references to the strings intended as keys.
| [reply] [d/l] |
|
my @atags = qw( 1 2 3 4 );
my @btags = qw( 9 8 7 6 );
my %alphabet = (
'a' => \@atags,
'b' => \@btags,
);
say for @{values %alphabet};
output:
Can't use string ("2") as an ARRAY ref while "strict refs" in use at
./concat.pl line 9 (#1)
(F) Only hard references are allowed by "strict refs". Symbolic
references are disallowed. See perlref.
Uncaught exception from user code:
Can't use string ("2") as an ARRAY ref while "strict refs" in use
+at ./concat.pl line 9.
at ./concat.pl line 9
| [reply] [d/l] [select] |
|
| [reply] [d/l] |
Re: Dereferencing a Hash of Arrays
by stefbv (Curate) on Jun 14, 2011 at 07:00 UTC
|
say for values %alphabet;
Updated as jwkrahn suggested, thanks. | [reply] [d/l] |
|
| [reply] |
|
Yes, I should 'use strict' when explaining about Perl functions :)
| [reply] |
|
Well, it returns two arrays. How do I get the program to spit out [1, 2, 3, 4]; [9, 8, 7, 6] ?
| [reply] [d/l] |
|
Only one :), with 2 array refs. (AoA)
say "@$_" for values %alphabet;
| [reply] [d/l] |
|
|
|
|