Ram
Ram

Reputation: 1213

Hash of arrays printing garbage values

I am trying to print data from a hash of arrays in a perl program. But it prints some garbage values along with original data:

#!/usr/bin/perl

my %Quarter = (
                June => ["06/03/2012", "06/10/2012", "06/17/2012", "06/24/2012"],
                July => ["07/01/2012", "07/08/2012", "07/15/2012", "07/22/2012"],
                August => ["08/05/2012", "08/12/2012", "08/19/2012", "08/26/2012"],
);


foreach my $month ( %Quarter ) {
        print "$month\n";
}

output:

July
ARRAY(0x9281af8)
June
ARRAY(0x9281bdc)
August
ARRAY(0x929ade8)

Any idea what is going wrong in this program.

Thanks

Upvotes: 1

Views: 1215

Answers (5)

cslotty
cslotty

Reputation: 1797

Your question hasn't been answered - if I'm not wrong.... I'd say, the "garbage" that you're seeing is not the data, but it says what it is, it's anonymous ARRAYs you're assigning to your hash keys.

So taking your code it should be:

#!/usr/bin/perl

my %Quarter = (
            June => ["06/03/2012", "06/10/2012", "06/17/2012", "06/24/2012"],
            July => ["07/01/2012", "07/08/2012", "07/15/2012", "07/22/2012"],
            August => ["08/05/2012", "08/12/2012", "08/19/2012", "08/26/2012"],
);


#foreach my $month ( %Quarter ) {
#    print "$month\n";
#}
while(my ($k,$v) = each %Quarter) {
  foreach my $x (@$v) {
    print $x."\n";
  }
}

Upvotes: 0

memowe
memowe

Reputation: 2668

Others answered the question on how to iterate over the day arrays, but the problem with printing months in the right order is that hashes aren't ordered. I have two possible solutions for this.

The first involves iterating over the month keys manually like this:

foreach my $month_name (qw(June July August)) {
    print $month_name . ': ' . join ', ' => @{$Quarter{$month_name}};
}

Or you need to provide the data structure as an array of hashes:

my @months = (
    {name => 'June', days => ["06/03/2012", "06/10/2012", "06/17/2012", "06/24/2012"]},
    # ...
);

foreach my $month (@months) {
    print $month->{name} . ': ' . join ', ' => @{$month->{days}};
}

TIMTOWTDI! Hope that helps. :)

Upvotes: 2

Toto
Toto

Reputation: 91385

In the foreach loop, $month is a reference to an array, you have to do

use Data::Dumper;
print Dumper\%Quarter;

or

foreach my $month (keys %Quarter ) {
    print "$_\n" for @{$Quarter{$month}};
}

Upvotes: 1

user507077
user507077

Reputation:

In Perl a hash can be trivially converted to an array with an equal number of elements. Each even numbered element is a key and the following (odd numbered) element is the corresponding value.

Now, foreach is an operator that iterates over arrays, not over hashes. Therefore your code does what it does: the loop variable iterates over a key, a value, the next key, next value etc.

There are several ways in which you can iterate over a hash:

  1. Iterate over all key/value pairs. You usually do that with something like while (my ($key, $value) = each %hash) { ... }
  2. Retrieve all keys from a hash and iterate over those: foreach my $key (keys %hash) { ... }
  3. If you don't need the keys and only the values then you can also tetrieve all values from the hash and iterate over those with foreach my $value (values %hash) { ... }

Upvotes: 3

Matt K
Matt K

Reputation: 13852

What are you trying to do? If you want to print the month names, you need to loop over keys %Quarter. If you want keys and values paired up, use each. If you use a hash in an array context like this, you get all keys and all values.

foreach my $month ( keys %Quarter ) {
        print "$month\n";
}

Upvotes: 0

Related Questions