Update: Upon re-reading your post I now realize that you asked something much simpler than what I answered (basically I misinterpreted the word "data" in your question). borisz is right; your second approach will work, though you can save yourself a bit of typing by omitting the -> 's:

for my $k (@sorted_keys) { $hash{$type}{$k}{data} = shift @mydata; }
I still think my original answer may be of some use to you.

The closest that I can come to what you have written is something like this:

my @subfields = qw( REQ POS LENGTH data FILTER ); my @sorted_keys = sort qw( field1 field2 ); my @mydata = ( [ 'Y', 34, 10, ' ' x 10, \&default_filter ], [ 'Y', 35, 10, ' ' x 10, \&default_filter ] ); my $type = 'that_type'; for my $k (@sorted_keys) { @{ $hash{$type}{$k} }{ @subfields } = @{ shift @mydata }; }
which doesn't seem to me terribly convenient. An improvement would be:
use strict; my @subfields = qw( REQ POS LENGTH data FILTER ); my @mydata = ( [ this_type => [ 'N', 34, 10, ' ' x 10, \&default_filter ] ], [ that_type => [ 'Y', 34, 10, ' ' x 10, \&default_filter ], [ 'Y', 35, 10, ' ' x 10, \&default_filter ] ], ); my %hash; for my $d ( @mydata ) { my $type = shift @$d; for my $data ( @$d ) { my $field; @{ $field }{ @subfields } = @$data; push @{ $hash{ $type } }, $field; } } __END__ DB<2> x \%hash 0 HASH(0x82ea2dc) 'that_type' => ARRAY(0x8449fa0) 0 HASH(0x8449f10) 'FILTER' => CODE(0x814cdd4) -> &CODE(0x814cdd4) in ??? 'LENGTH' => 10 'POS' => 34 'REQ' => 'Y' 'data' => ' ' 1 HASH(0x8449fac) 'FILTER' => CODE(0x814cdd4) -> REUSED_ADDRESS 'LENGTH' => 10 'POS' => 35 'REQ' => 'Y' 'data' => ' ' 'this_type' => ARRAY(0x8449ef8) 0 HASH(0x8449e20) 'FILTER' => CODE(0x814cdd4) -> REUSED_ADDRESS 'LENGTH' => 10 'POS' => 34 'REQ' => 'N' 'data' => ' '
As you can see, I got rid of the fieldn keys (in this regard you may want to read this node). Now the values of %hash are (references to) arrays containing (references to) hashes. E.g., to access the LENGTH subfield of the second field of that_type, you'd use
$hash{ that_type }[ 1 ]{ LENGTH }

Also note that

\&default_filter()
and
\&default_filter
mean different things. The former (which is what you used in your code), evaluates to a reference pointing to whatever the subroutine default_filter returns. In contrast, the latter evaluates to a reference to the subroutine default_filter itself. In the code I posted, I assumed that what you really wanted was the latter.

the lowliest monk


In reply to Re: hash assignment in complex structure by tlm
in thread hash assignment in complex structure by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.