in reply to Re: how to extract data from an array using a condition
in thread how to extract data from an array using a condition

Thanks for your reply, it was very helpful. I am not very familiar with array of hashes, how do you access elements from @data using the header names? I tried several ways but with no success. Thanks you all for your replies.

  • Comment on Re^2: how to extract data from an array using a condition

Replies are listed 'Best First'.
Re^3: how to extract data from an array using a condition
by bart (Canon) on Jun 21, 2011 at 10:56 UTC
    You can get to grips with the basics at: but I'll quickly describe the concepts here.

    An array of hashes is a plain, one-dimensional array, where the items are references to hashes. Now in perl, in contrast with other languages like PHP and Javascript, a hash ref is not the same as a hash. A has is a data structure; a hash ref is a reference, a scalar, a single value, which points to a hash. As a result, there are rather subtle differences in syntax. If %hash is a hash, then $ref = \%hash; now is a reference to that hash, "hash ref" for short. I'll stress that it's the same hash, and not a copy. That means if you change a value in one, you'll see the same change in the other too. They're just different ways to access the same content data.

    The basic syntax is:
    hashhash ref
    reference\%hash$ref
    hash%hash%$ref
    element$hash{'key'}$ref->{'key'} or ${$ref}{$key} or $$ref{'key'}
    hash slice@hash{'one','two'}@{$ref}{'one','two'}

    So you need an array to access an item in a hash. That array is optional only between level indexes (either between square brackets or curly braces): $deep[0]->{'key'} is the same as $deep[0]{'key'}.

    The block around the reference for dereferencing (which is what we call accessing content in the data structure the reference points to) is not always necessary, but when you have a precedence problem, it's advisable to use one. (Thus: curly braces, not parentheses!)

    You can now choose to access, for example, the 'sex' of a single data row directly, as

    $data[0]{'sex'}
    or, via an explicit reference in a loop:
    foreach my $row (@data) { print $row->{'sex'}; }

    Oh, I forgot. Note that grep (and map) is actually a loop in a different syntax, where in the (loop) block you can access each item in turn via $_ (instead of $row). grep is a good way to filter in a list: if the last expression evaluated in the block is true, then the current value of $_ is pushed onto the result list that it returns. map is similar except it pushes the last values (as a list) encountered, irrespective of its values.