On May 26, 8:17 am, [EMAIL PROTECTED] (Pauld) wrote:
> ive read a load of data in from a CSV file with Text::CSV and ended
> up with a hash (%hash) where the keys are the column labels.
> my @headings=split(/,/,$rows[0])
You're use()'ing Text::CSV, but you're not actually using Text::CSV.
Why?
> and then
>
> for (my $j=1;$j<$#rows;$j++)
Is there a reason you're ignoring the last row completely?
> {
> my $status = $csv->parse ($rows[$j]); # parse a CSV string into
> fields
Storing the status is rather pointless if you don't bother actually
checking it. . .
> my @columns = $csv->fields (); # get the parsed fields
>
> for (my $i=0;$i<$#columns;$i++)
Now you're ignoring the last column. Do you understand that $#foo is
the *last index* of @foo, and so looping until less than $#foo stops
before the last element?
> {$hash{$headings[$i]}=$columns[$i];}
Of course, that entire loop would be better served to be a hash
slice...
>
> I want to process the data once its grouped by the date field present
> in $hash. So i think I want a hash of dates where the key is that
> date field
> I push onto the value the hashes of the records that contain the date
>
> push @{$Hofdates{$hash{DATE}}},\%hash;
>
> but im having a problem working out how to access the individual
> items in the hashes that are elements of the array
You should read:
perldoc perllol
perldoc perldsc
Go step by step:
(1) %Hofdates is your overall hash.
(2) $Hofdates{'2007-05-26'} is one element of the hash. That element
is a reference to an array.
(3) @{$Hofdates{'2007-05-26'}} is the array that (2) references.
(4) ${$Hofdates{'2007-05-26'}}[0] is the first element of (3). That
element is a reference to a hash.
(5) %{${$Hofdates{'2007-05-26'}}[0]} is the hash that (4) references.
(6) ${${$Hofdates{'2007-05-26'}}[0]}{NAME} is the value of (5) at the
key 'NAME'
(7) $Hofdates{'2007-05-26'}[0]{NAME} is the same as (6), but with all
unnecessary punctuation removed. (See perldocs listed above)
Once you get used to Perl's multi-level structures, you'll find you
don't need to go through this process, as the end result just "makes
sense".
Please note, whenever possible, please try to post a short-but-
complete script that demonstrates what you're trying to do. That way
we can help you see what you might have done wrong. For example:
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
use Data::Dumper;
my $csv = Text::CSV->new();
my %records_for;
my $heading = <DATA>;
$csv->parse($heading)
or die "Could not parse '$heading'. Failed on " . $csv-
>error_input;
my @heading = $csv->fields();
while (my $line = <DATA>) {
$csv->parse($line)
or die "Could not parse line $.. Failed on " . $csv->error_input;
my @columns = $csv->fields();
my %hash;
#use a hash slice rather than a for loop.
@[EMAIL PROTECTED] = @columns;
push @{$records_for{$hash{DATE}}}, \%hash;
}
#Take a look at your structure.
print Dumper(\%records_for);
#Get the name of the 2nd record with date '2007-05-26';
print $records_for{'2007-05-26'}[1]{'NAME'}, "\n";
#or, get the names of all records:
foreach my $date (keys %records_for) {
my $i = 0;
foreach my $record (@{$records_for{$date}}) {
print "$date($i): $record->{NAME}\n";
$i++;
}
}
__DATA__
NAME,DATE,COLOR,SIZE
Paul,2007-05-26,blue,large
John,2007-04-21,red,small
Mary,2007-05-26,orange,medium
Peter,2006-01-30,blue,small
Hope this helps,
Paul Lalli
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/