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

Hi Monks!

Trying to convert this array of arrays into array of hashes, but as you can see, I am stuck:
Me Data:
@data = [ [ "JOHN JR", "10/30/2011", "Main Street, ] [ "JOE DOE", "11/30/1999", "Broke Street", ] [ "MARY DEE", "06/01/2014", "Pearl Street", ] ]
Test code:
#!/usr/bin/perl use strict; use warnings; my @AoH; for my $row ( 0..$#data ) { push @AoH, { NAME => $data[0], DOB => $data[1], ADDRRESS => $data[2], }; }

Thanks for the help!

Replies are listed 'Best First'.
Re: Array to Array of hashes
by kcott (Archbishop) on Oct 27, 2015 at 16:51 UTC

    You have issues with your initial data:

    • Assigning an arrayref to an array: @data = [...]
    • Unterminated string: "Main Street,
    • Failure to separate array elements: @data = [[...][...][...]]

    I strongly recommend that you use the strict and warnings pragmata in all your code.

    There's documentation on complex data structures. These may be a good place to start:

    I've had to make some changes to your initial data; however, the following is probably close to what you want.

    #!/usr/bin/env perl use strict; use warnings; use Data::Dump; my @data = ( [ "JOHN JR", "10/30/2011", "Main Street"], [ "JOE DOE", "11/30/1999", "Broke Street"], [ "MARY DEE", "06/01/2014", "Pearl Street"] ); my @AoH; @{$AoH[@AoH]}{qw{NAME DOB ADDRESS}} = @$_ for @data; dd \@AoH;

    Output:

    [ { ADDRESS => "Main Street", DOB => "10/30/2011", NAME => "JOHN JR" } +, { ADDRESS => "Broke Street", DOB => "11/30/1999", NAME => "JOE DOE" +}, { ADDRESS => "Pearl Street", DOB => "06/01/2014", NAME => "MARY DEE" + }, ]

    — Ken

Re: Array to Array of hashes
by NetWallah (Canon) on Oct 27, 2015 at 16:33 UTC
    There are at least 2 issues:
    • @data is an array, but is being assigned an array-REF. Use Parens(), instead of square brackets[] for the outermost delimiter
    • the "for" statement aliases $_ to each element. So in you case, you should be using $_ as the index, instead of your hard-coded "1" and "2"
    • A perl programmer would prefer "for (@data)" instead of "for (0..$#data)"

            The best defense against logic is ignorance.

      The data was a Dump from the array @data, but how you were saying, how would you use "$_" instead of assigning or hard-code "1" and "2" ... to the code?
      my @data = ( ["John","10/30","Main Street"], ["Mary","6/1","Oak Street"] # more data here ); foreach (@data) { push @AoH, { NAME => $_, DOB => $_, ADDRESS => $_, } }
      Thanks!
Re: Array to Array of hashes
by GotToBTru (Prior) on Oct 27, 2015 at 16:38 UTC

    I think your data structure is not what you intend. Your @data has only 1 row (an array ref), instead of 3 rows, each one an array.

    Try instead (as NetWallah suggests):

    @data = ( ["John","10/30","Main Street"], ["Mary","6/1","Oak Street"] ); foreach my $aref (@data) { push @AoH, { NAME => $aref->[0], ...
    Dum Spiro Spero
Re: Array to Array of hashes
by stevieb (Canon) on Oct 27, 2015 at 16:41 UTC

    You're putting a number into $row on each iteration over data, and then not using it. It's more idiomatic to put each element of @data into $row, then work on that.

    for my $row (@data){ push @aoh, { name => $row->[0], dob => $row->[1], addr => $row->[2], }; }

    PS: Your @data array is corrupt. First, you're missing a closing double-quote, and further, you create an array and then immediately assign an array reference to it as it's first element. Please ensure that your data and code compile properly before posting it, unless of course that's the specific problem you don't understand. For an array, you use parens, like so: my @array = (1, 2, ...);

Re: Array to Array of hashes
by Laurent_R (Canon) on Oct 27, 2015 at 16:46 UTC
    Hi,

    try this:

    use strict; use warnings; use Data::Dumper; my @data = ( [ "JOHN JR", "10/30/2011", "Main Street", ], [ "JOE DOE", "11/30/1999", "Broke Street", ], [ "MARY DEE", "06/01/2014", "Pearl Street", ], ); my @AoH; for my $row (@data) { push @AoH, { NAME => $row->[0], DOB => $row->[1], ADDR => $row->[2 +]}; } print Dumper \@AoH;
    This gives the following output:
    $VAR1 = [ { 'NAME' => 'JOHN JR', 'DOB' => '10/30/2011', 'ADDR' => 'Main Street' }, { 'NAME' => 'JOE DOE', 'DOB' => '11/30/1999', 'ADDR' => 'Broke Street' }, { 'NAME' => 'MARY DEE', 'DOB' => '06/01/2014', 'ADDR' => 'Pearl Street' } ];
    Please notice that I have made a number of changes to your original data (an array instead of an array ref, adding commas, adding a closing quote, etc.). Your original data would not even compile (at least not under use strict; use warnings;).