8

Examples:

%hash = (2010 => 21, 2009=> 9);

$hash = {
    a => {
        0 => {test => 1},
        1 => {test => 2},
        2 => {test => 3},
        3 => {test => 4},
    },
};

How do I print the hash?

FMc
  • 41,963
  • 13
  • 79
  • 132
Sourabh
  • 81
  • 1
  • 1
  • 3
  • Also see this question: http://stackoverflow.com/questions/2363142/how-to-iterate-through-hash – FMc Mar 12 '10 at 12:53
  • See the Perl Data Structures Cookbook - perldoc perldsc on the command line or at http://perldoc.perl.org/perldsc.html – daotoad Mar 12 '10 at 15:43

9 Answers9

20

Do you want to print the entire hash, or specific key, value pairs? And what is your desired result? IF it's just for debugging purposes, you can do something like:

use Data::Dumper;
print Dumper %hash; # or \%hash to encapsulate it as a single hashref entity;

You can use the each function if you don't care about ordering:

while ( my($key, $value) = each %hash ) {
    print "$key = $value\n";
}

Or the for / foreach construct if you want to sort it:

for my $key ( sort keys %hash ) {
    print "$key = $hash{$key}\n";
}

Or if you want only certain values, you can use a hash slice, e.g.:

print "@hash{qw{2009 2010}}\n";

etc, etc. There is always more than one way to do it, though it helps to know what you're frying to do first :)

friedo
  • 65,762
  • 16
  • 114
  • 184
Duncan
  • 2,056
  • 13
  • 11
  • I may be wrong but I believe the OP hash problems with syntax to access items or even hash using hash references, not with iterators on hashes. Notice than in his second exemple his variable is a scalar $hash, not a hash. – kriss Mar 12 '10 at 08:30
  • @kriss: The original question asked how to print a hash, it would appear the OP has edited the question with a further example. The first example of using Data::Dumper will still handle that correctly. – Duncan Mar 13 '10 at 01:20
  • @Duncan: Data::Dumper works everywhere. On the other hand there is more than printing data ;-) – kriss Mar 13 '10 at 20:56
  • @kriss: There is more to printing a hash than printing data? The question is "How do I print a hash structure in Perl?" :) – Duncan Mar 13 '10 at 22:16
2
  while( my( $key, $value ) = each( %hash ) ) {
         ...
  }
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
2

instead of

%hash = { 2010=> 21, 2009=> 9 }

you should write

%hash = ( 2010=> 21, 2009=> 9 ); 

with the curly braces you get a REFERENCE to an anonymous hash, which is then stored as the first key of you %hash.

bjelli
  • 9,752
  • 4
  • 35
  • 50
  • 2
    and worse, it's stored in stringified form! – Philip Potter Mar 12 '10 at 08:12
  • yes, but in his **second** exemple the OP wrote : $h = { some content }; and **that** may be legitimate (say to pass a hash reference to a sub). (Even if you are probably right and it is a newbie mistake). – kriss Mar 12 '10 at 08:32
2

Syntax to access inner cells for your second example is like:

print $hash->{"a"}{0}{"test"}

That will give you 1 in your example.

If you want to iterate on it, you can do it as follows (print lines are for illustration purposes):

my $hash = {"a"=>{ 0=>{"test"=>1}, 1=>{"test"=>2}, 2=>{"test"=>3}, 3=>{"test"=>4} } };
print "Direct access to item : ".$hash->{"a"}{1}{"test"}."\n";

foreach my $k1 (keys(%$hash)) {
    print "keys of level 1: $k1\n";
    foreach my $k2 (keys(%{$hash->{$k1}})) {
        print "keys of level 2: $k2\n";
        print "values: ".$hash->{$k1}{$k2}{"test"}."\n"
     }
}

Notice that things are a bit more tricky than necessary because the external $hash is a scalar reference to an anonymous hash. It would be simpler if it was a hash (i.e., like in my %hash = (1, 2); print $hash{1};).

(TIMTOWTDI: there is obviously more than one way to do it; I believe the above example is the simplest for me, but not the most efficient; using each instead of keys for iterating would avoid one unnecessary hash lookup).

kriss
  • 23,497
  • 17
  • 97
  • 116
  • 1
    Most programmers do not write double sigils and repeated arrows. This notation is much more readable: `$hash->{'a'}{0}{'test'}` – daxim Mar 12 '10 at 10:32
  • @daxim: yes, i tried to make it more explicit for beginner but I probably failed on this one. I will change it. – kriss Mar 12 '10 at 14:04
  • Recursion is probably too advanced at this stage? – Duncan Mar 13 '10 at 02:04
  • @Duncan: probably, but I don't really see where you want to put recursion in that question ? Some example on how to use hashes to make trees or graphs ? – kriss Mar 13 '10 at 21:17
1

you can try with this,

while(my ($key,$val)=each %HASH){
print $key," = ",$val,"\n";
while(my ($kkey,$vval)=each %{$HASH{$key}}){
print "   ",$kkey," = ",$vval,"\n";
}
}
velepost
  • 11
  • 1
  • Did you try it? What is the result of the first print: `print $key," = ",$val,"\n";` – Toto Dec 16 '14 at 16:13
0

use keys , values function

@keys = keys %hash ; 

@values = values %hash 
Pavunkumar
  • 5,147
  • 14
  • 43
  • 69
0

This should help:

foreach $key (keys %hash)
{
  print "key is : $key, value is : $hash{$key}\n";
}

cheers

Arnkrishn
  • 29,828
  • 40
  • 114
  • 128
  • Thanks for reply if my hash is like this $hash = {'a'=>{ 0=>{'test'=>'1'}, 1=>{'test'=>'2'}, 2=>{'test'=>'3'}, 3=>{'test'=>'4'} } }; Then what I will do – Sourabh Mar 12 '10 at 07:36
0
printf ("%s = %s\n", $_, $hash {$_}) foreach (keys (%hash));
friedo
  • 65,762
  • 16
  • 114
  • 184
Jeff
  • 19
0

The function printStruct below works using recursion and can print hashes of arrays, arrays of hashes or any mixture thereof to any depth. You call it with a reference to your structure, and a name of the structure in a string. The last input $pre is only used during the recursion to tell the initial entry into the recursive function. Just leave it blank when you call the function.

%hash = (2010 => 21, 2009=> 9);
printStruct(\%hash,"\%hash");

$hash = {
    a => {
        0 => {test => 1},
        1 => {test => 2},
        2 => {test => 3},
        3 => {test => 4},
    },
};
$hash->{b}=[1..5];
printStruct($hash,"\$hash");
my @array=[apple,banana,orange,$hash];
printStruct(\@array,"\@array");

sub printStruct {
    my ($struct,$structName,$pre)=@_;
    print "-----------------\n" unless (defined($pre));
    if (!ref($struct)){ # $struct is a scalar.
    print "$structName=$struct\n";
    } elsif (ref($struct) eq "ARRAY") { # Struct is an array reference
    return ("ARRAY(".scalar(@$struct).")") if (@$struct>100);
    for(my$i=0;$i<@$struct;$i++) {
        if (ref($struct->[$i]) eq "HASH") {
        printStruct($struct->[$i],$structName."->[$i]",$pre." ");
        } elsif (ref($struct->[$i]) eq "ARRAY") { # contents of struct is array ref
        print "$structName->"."[$i]=()\n" if (@{$struct->[$i]}==0);
        my $string = printStruct($struct->[$i],$structName."->[$i]",$pre." ");
        print "$structName->"."[$i]=$string\n" if ($string);
        } else { # contents of struct is a scalar, just print it.
        print "$structName->"."[$i]=$struct->[$i]\n";
        }
    }
    return();
    } else { # $struct is a hash reference or a scalar
    foreach (sort keys %{$struct}) {
        if (ref($struct->{$_}) eq "HASH") {
        printStruct($struct->{$_},$structName."->{$_}",$pre." ");
        } elsif (ref($struct->{$_}) eq "ARRAY") { # contents of struct is array ref
        my $string = printStruct($struct->{$_},$structName."->{$_}",$pre." ");
        print "$structName->"."{$_}=$string\n" if ($string);
        } else { # contents of struct is a scalar, just print it.
        print "$structName->"."{$_}=$struct->{$_}\n";
        }
    }
    return();
    } 
    print "------------------\n" unless (defined($pre));
    return();
}

Result:

-----------------
%hash->{2009}=9
%hash->{2010}=21
-----------------
$hash->{a}->{0}->{test}=1
$hash->{a}->{1}->{test}=2
$hash->{a}->{2}->{test}=3
$hash->{a}->{3}->{test}=4
$hash->{b}->[0]=1
$hash->{b}->[1]=2
$hash->{b}->[2]=3
$hash->{b}->[3]=4
$hash->{b}->[4]=5
-----------------
@array->[0]->[0]=apple
@array->[0]->[1]=banana
@array->[0]->[2]=orange
@array->[0]->[3]->{a}->{0}->{test}=1
@array->[0]->[3]->{a}->{1}->{test}=2
@array->[0]->[3]->{a}->{2}->{test}=3
@array->[0]->[3]->{a}->{3}->{test}=4
@array->[0]->[3]->{b}->[0]=1
@array->[0]->[3]->{b}->[1]=2
@array->[0]->[3]->{b}->[2]=3
@array->[0]->[3]->{b}->[3]=4
@array->[0]->[3]->{b}->[4]=5

This function helped in a lot of programming and debugging of complex structures. I hope you guys find it as useful.

Chah
  • 151
  • 5