I'm writing some tests for the Mainstreet Credit Verification Engine and I need to create some reports based upon CSV data that the engine parses for me. I don't have access to the raw CSV data, so I have to write a routine that uses their interface. I am trying to create a hashref with one key being the report headers (in the order they exist) and the second key being an arrayref of hashrefs with the data that I need. For example, with csv data like the following:

foo,bar
333,aaa
444,bbb
555,ccc

I'd like to create the following data structure:

$VAR1 = {
          'data' => [
                      {
                        'foo' => '333',
                        'bar' => 'aaa'
                      },
                      {
                        'foo' => '444',
                        'bar' => 'bbb'
                      },
                      {
                        'foo' => '555',
                        'bar' => 'ccc'
                      }
                    ],
          'headers' => [
                         'foo',
                         'bar'
                       ]
        };

The code that I am using is as follows (stripped of non-essential features):

#!/usr/bin/perl use strict; use Data::Dumper; # testing _get_csv local *MCVE::MCVE_Ub = sub { [qw/ 333 444 /] }; local *MCVE::MCVE_NumRows = sub { 3 }; local *MCVE::MCVE_NumColumns = sub { 2 }; my @columns = ('foo', 'bar'); local *MCVE::MCVE_GetHeader = sub { shift @columns }; my @rows = qw/ 333 aaa 444 bbb 555 ccc /; local *MCVE::MCVE_GetCellByNum = sub { shift @rows }; my $report = _get_csv(); print Dumper $report; sub _get_csv { my $rows = MCVE::MCVE_NumRows(); my $columns = MCVE::MCVE_NumColumns(); my %report; my @headers; my @data = ({}) x ($rows-1); # need an extra for the header foreach my $column ( 0 .. $columns - 1 ) { push @headers, MCVE::MCVE_GetHeader( $column ); } $report{headers} = \@headers; foreach my $row ( 0 .. $rows - 1 ) { my @temp; foreach my $column ( 0 .. $columns - 1 ) { push @temp, MCVE::MCVE_GetCellByNum($column,$row ); } warn "Temp: '@temp' added to row $row "; @{$data[$row]}{ @headers } = @temp; } $report{data} = \@data; return \%report; }

I think you can guess what the functions are trying to do :)

Note that this snippet is for unit testing (making sure my algorithm is correct) rather than integration testing, which is why I localize all of the functions.

The problem is in the output:

Temp: '333 aaa' added to row 0  at C:\test.pl line 39.
Temp: '444 bbb' added to row 1  at C:\test.pl line 39.
Temp: '555 ccc' added to row 2  at C:\test.pl line 39.
$VAR1 = {
          'data' => [
                      {
                        'foo' => '444',
                        'bar' => 'bbb'
                      },
                      $VAR1->{'data'}[0],
                      {
                        'foo' => '555',
                        'bar' => 'ccc'
                      }
                    ],
          'headers' => [ 
                         'foo',
                         'bar'
                       ]
        };

As you can see from the warning lines, I appear to be building my temp data correctly and even assigning it to the correct row in the array ref, but element 0 (444 bbb) should be (333 aaa). What the heck am I doing wrong?

Cheers,
Ovid

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.


In reply to Why is my data structure wrong? by Ovid

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.