Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi perl monks. I am stumped with this one.

I have several arrays that I want to slice into a single hash ref. Any tips? I read a bit about creating a hash slice from 2 arrays, but can't figure out the syntax for creating a hash ref slice from multiple arrays.

For example (excuse grammatical errors -- this is more pseudo code than anything):

$hash_ref; @array1 = "some_unique_key1 some_unique_key2 some_unique_key3"; @array2 = "meta_data_1 metadata_2 metadat_3"; @array3 = "submitted_date1 submitted_date2 submitted_date3";

The hash ref would have a structure like:

$some_uniquekey1 --> 'Metadata' --> $meta_data1 = '1' --> 'Submitted Date' --> $subitted_date1 = '1' $some_uniquekey2 ... etc $some_uniquekey3 ... etc

Basically the arrays value indices all correspond to each other -- I just want to merge them all into an accessible table.

Any tips or slaps up the side of my head appreciated!

Replies are listed 'Best First'.
Re: Populating a hash-ref from multiple arrays with slice?
by toolic (Bishop) on Apr 16, 2015 at 17:42 UTC
    A single loop works to create a hash-of-hashes:
    use warnings; use strict; my @a1 = map{"k$_"} 1..3; my @a2 = map{"m$_"} 1..3; my @a3 = map{"d$_"} 1..3; my $href; for my $i (0 .. $#a1) { $href->{$a1[$i]} = {Metadata => $a2[$i], Submitted => $a3[$i]}; } use Data::Dumper; $Data::Dumper::Sortkeys=1; print Dumper($href); __END__ $VAR1 = { 'k1' => { 'Metadata' => 'm1', 'Submitted' => 'd1' }, 'k2' => { 'Metadata' => 'm2', 'Submitted' => 'd2' }, 'k3' => { 'Metadata' => 'm3', 'Submitted' => 'd3' } };

    perldsc

Re: Populating a hash-ref from multiple arrays with slice?
by jeffa (Bishop) on Apr 16, 2015 at 17:41 UTC

    The problem is that you have to store multiple values into an anonymous array ref, and hash slices implicitly loop on lists, not a scalar that points to an anonymous array ref. How about the old fashioned way instead?

    use strict; use warnings; use Data::Dumper; my %hash; my @array1 = qw"some_unique_key1 some_unique_key2 some_unique_key3"; my @array2 = qw"meta_data_1 metadata_2 metadat_3"; my @array3 = qw"submitted_date1 submitted_date2 submitted_date3"; for (0 .. $#array1) { $hash{ $array1[$_] } = [ $array2[$_], $array3[$_] ]; } print Dumper \%hash;

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: Populating a hash-ref from multiple arrays with slice?
by hdb (Monsignor) on Apr 16, 2015 at 17:52 UTC

    I cannot see a way to make it work using slices. This here utilizes slices but creates a different structure:

    use strict; use warnings; use Data::Dumper; my $hash_ref; my @array1 = qw( some_unique_key1 some_unique_key2 some_unique_key3 ); my @array2 = qw( meta_data_1 metadata_2 metadat_3 ); my @array3 = qw( submitted_date1 submitted_date2 submitted_date3 ); @{$hash_ref->{'Metadata'}}{ @array1 } = @array2; @{$hash_ref->{'Submitted date'}}{ @array1 } = @array3; print Dumper $hash_ref;

    creates

    $VAR1 = { 'Metadata' => { 'some_unique_key3' => 'metadat_3', 'some_unique_key2' => 'metadata_2', 'some_unique_key1' => 'meta_data_1' }, 'Submitted date' => { 'some_unique_key3' => 'submitted_date3 +', 'some_unique_key2' => 'submitted_date2 +', 'some_unique_key1' => 'submitted_date1 +' } };
Re: Populating a hash-ref from multiple arrays with slice?
by NetWallah (Canon) on Apr 16, 2015 at 18:16 UTC
    Slices would not be useful for this problem.

    Here is the equivalent of toolic's solution, in one line:

    my $h={map{$a1[$_]=>{Metadata=>$a2[$_],Submitted=>$a3[$_]}}0..$#a1};

            "You're only given one little spark of madness. You mustn't lose it."         - Robin Williams

      But if the OP wants it as slice, this is the code:

      @array1 = qw(some_unique_key1 some_unique_key2 some_unique_key3); @array2 = qw(meta_data_1 metadata_2 metadat_3); @array3 = qw(submitted_date1 submitted_date2 submitted_date3); my $hashref; # @hash{@keys} = @values; @$hashref{@array1} = map { {'Metadata' =>$array2[$_], 'Submitted Date' +=>$array3[$_]} } 0..$#array1; use Data::Dumper; die Dumper $hashref;

      It would then give this as output:

      $VAR1 = { 'some_unique_key3' => { 'Submitted Date' => 'submitted_date3', 'Metadata' => 'metadat_3' }, 'some_unique_key2' => { 'Submitted Date' => 'submitted_date2', 'Metadata' => 'metadata_2' }, 'some_unique_key1' => { 'Submitted Date' => 'submitted_date1', 'Metadata' => 'meta_data_1' } };

        Rate netWallah hashref toolic jeffa netWallah 324041/s -- -16% -16% -35% hashref 387028/s 19% -- -0% -22% toolic 387777/s 20% 0% -- -22% jeffa 497471/s 54% 29% 28% --
        Note that Jeffa's code is faster because it uses HoA, and not HoH. if you then use constants to access 0 and 1 it could be the way to go.