in reply to print array of hashes

how to print this structure?
How can I visualize my complex data structure?

Replies are listed 'Best First'.
Re^2: print array of hashes
by fionbarr (Friar) on Apr 22, 2010 at 14:29 UTC
    $num_kids = (scalar @{$rec[0]{kids}}); $num_kids = scalar (@{$rec[0]->{kids}});
    both these work...would someone be so kind as to explain each of them?
      @rec is an array of hashrefs, therefore $ref[0] is a hashref. The arrow is optional here, we have two possible ways to get the value of the kids key. The value is an arrayref, so we dereference it with @{} to get the array. And scalar applied to a list an array returns the number of elements in it.

      Update: rephrased because of almut's reply.

        And scalar applied to a list returns the number of elements in the list.

        That statement could be misleading...:

        $num = scalar ( qw(foo bar) ); print $num; # "bar", not 2!

        A list (as opposed to an array) in scalar context evaluates to its last element.

        this site amazes me...the helpfulness of the participants is something else...thanks, all.
      When you see an index like [0] in Perl code, this is a RED alert that probably something is wrong, not always but, more likely than not!!

      You have an array of "pointers" to anon hashes. Data::Dumper is a SUPER cool thing to help visualize what is going on.

      Below, I have a foreach loop that processes every hash_ref in @rec.
      $hash_ref->{'name'} yields the name in that record
      @{$hash_ref->{'kids'}} is a bit trickier. If this was just one kid, then it would work like a name. But there are multiple kids and this is an array of kids.
      Below I show how to print @demo. $hash_ref->{'kids'} fetches one thing just like accessing $hash_ref->{'name'} did. But now we have to de-reference that single thing which is a "pointer" to array. In Perl when you have a "subscripted thing" and you want to de-reference it, you need to enclose it in brackets,{}. I did that, then I said that this is an array de-reference '@' and bingo, this is now just like printing @demo. In other words, you need to tell "@" what to operate upon. @$hash_ref->{'kids'} would mean something completely different. I want "@" to operate not just upon the value $hash_ref, but upon the whole thing that {$hash_ref->{'kids'}} "points to".

      An array in a scalar context is the number of things in that array. I think others have covered that point.

      #!/usr/bin/perl -w use strict; use Data::Dumper; my @demo =('xyz', 'qrs'); my @rec = ( { name => 'Nancy', address => 613, kids => ['abc', 'def'], }, { name => "Betty", address => 845, kids => ['xyz', 'qrs'], }, ); print Dumper \@rec; print "DEMO: @demo\n"; foreach my $hash_ref (@rec) { print "$hash_ref->{'name'} struggles with: ", "@{$hash_ref->{'kids'}}\n"; } __END__ $VAR1 = [ { 'name' => 'Nancy', 'kids' => [ 'abc', 'def' ], 'address' => 613 }, { 'name' => 'Betty', 'kids' => [ 'xyz', 'qrs' ], 'address' => 845 } ]; DEMO: xyz qrs Nancy struggles with: abc def Betty struggles with: xyz qrs

      There are a couple of things going on here.

      First, you have the difference between:

      $val = (EXPRESSION);
      and
      $val = EXPRESSION;
      Here the parentheses act like they do in basic math, so, in this case, the two operations are identical.

      Next you have the difference between:

      scalar ARGS;
      and
      scalar(ARGS);
      For many perl functions (such as scalar), the parentheses surrounding the arguments are optional. It often reads more like a natural human sentence if you omit them, but often it is better to explicitly include them if the resulting statement does not read well as a natural human sentence.

      You might also want to know what @{EXPRESSION} means. This is how to dereference an array reference in perl. If $val holds a reference to an array (e.g. it does not hold the array itself), then @{$val} returns the actual array. Similarly you can use %{$val} to dereference the hash referenced by $val, ${$val} to dereference the scalar referenced by $val, and &{$val} to dereference the subroutine referenced by $val, with @{$val}(ARGS) if you need to pass arguments.

      Finally, there is the difference between:

      $rec[0]{kids}
      and
      $rec[0]->{kids}
      Each element in the @rec array is itself a reference to a hash. Perl provides these two ways to access the scalar held as a value in a hashref, which only differ in the use of the '->' operator. I recommend always using the '->' operator, which explicitly means 'the thing referenced by'. It is much more self documenting. $rec[0]->{kids} is the value keyed to 'kids' in the hash referenced by $rec[0]. Similarly, $array_ref->[0] is the first element in the array referenced by $array_ref, and $code_ref->() is the subroutine referenced by $code_ref. Also, $code_ref->(ARGS) is much more pretty than @{$code_ref}(ARGS). When you get into multidimensional data structures, the '->' can be very helpful. Compare the identically functioning:
      ${$aref}[0]{kids}[0]{first_name}
      and
      $aref->[0]->{kids}->[0]->{first_name}
      The last one is much more self-documenting, and really starts to look more like an object (which also uses '->' for attributes and methods, which should give you the impression that it is pretty powerful magic).