Re: accesing a hash of an array of hashes

2007-05-26 Thread Paul Lalli
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 = ;
$csv->parse($heading)
  or die "Could not parse '$heading'.  Failed on " . $csv-
>error_input;
my @heading = $csv->fields();
while (my $line = ) {
  $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/




Re: accesing a hash of an array of hashes

2007-05-26 Thread yaron


Hi,

To access element of a given DATE (sat ... date_inp) from Hofdates you can do 
the following:

my $date_inp = ... ;
die "No etries for date $date_inp" unless (exists $Hofdates{$date_inp} and 
@{$Hofdates{$date_inp}});
foreach my $hash_ref (@{$Hofdates{$date_inp}}) {
while (my ($field,$value) = each %$hash_ref) {
  print "Fieal = $field, value = $value\n";
 }
}

Hope that helps


Yaron Kahanovitch


- Original Message

 -
From: "pauld" <[EMAIL PROTECTED]>
To: beginners@perl.org, [EMAIL PROTECTED]
Sent: 14:17:57 (GMT+0200) Africa/Harare שבת 26 מאי 2007
Subject: accesing a hash of an array of hashes

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])
and then

for (my $j=1;$j<$#rows;$j++)
{
my $status  = $csv->parse ($rows[$j]);   # parse a CSV string into
fields
my @columns = $csv->fields ();   # get the parsed fields

for (my $i=0;$i<$#columns;$i++)
  {$hash{$headings[$i]}=$columns[$i];}

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


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: accesing a hash of an array of hashes

2007-05-26 Thread yaron
Hi,

Be aware that you have a small problem.
Your script includes:
for (my $j=1;$j<$#rows;$j++)
...
for (my $i=0;$i<$#columns;$i++)

I think It should be 
for (my $j=1;$j<=$#rows;$j++)
...
for (my $i=0;$i<=$#columns;$i++)


Cheers

Yaron Kahanovitch
- Original Message -
From: [EMAIL PROTECTED]
To: "pauld" <[EMAIL PROTECTED]>
Cc: "beginners" 
Sent: 19:47:38 (GMT+0200) Africa/Harare שבת 26 מאי 2007
Subject: Re: accesing a hash of an array of hashes



Hi,

To access element of a given DATE (sat ... date_inp) from Hofdates you can do 
the following:

my $date_inp = ... ;
die "No etries for date $date_inp" unless (exists $Hofdates{$date_inp} and 
@{$Hofdates{$date_inp}});
foreach my $hash_ref (@{$Hofdates{$date_inp}}) {
while (my ($field,$value) = each %$hash_ref) {
  print "Fieal = $field, value = $value\n";
 }
}

Hope that helps


Yaron Kahanovitch


- Original Message

 -
From: "pauld" <[EMAIL PROTECTED]>
To: beginners@perl.org, [EMAIL PROTECTED]
Sent: 14:17:57 (GMT+0200) Africa/Harare שבת 26 מאי 2007
Subject: accesing a hash of an array of hashes

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])
and then

for (my $j=1;$j<$#rows;$j++)
{
my $status  = $csv->parse ($rows[$j]);   # parse a CSV string into
fields
my @columns = $csv->fields ();   # get the parsed fields

for (my $i=0;$i<$#columns;$i++)
  {$hash{$headings[$i]}=$columns[$i];}

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


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: accesing a hash of an array of hashes

2007-05-26 Thread Mumia W.

On 05/26/2007 07:17 AM, 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])
and then

for (my $j=1;$j<$#rows;$j++)
{
my $status  = $csv->parse ($rows[$j]);   # parse a CSV string into
fields


You don't check $status to see if the parse succeeded.


my @columns = $csv->fields ();   # get the parsed fields

for (my $i=0;$i<$#columns;$i++)
  {$hash{$headings[$i]}=$columns[$i];}



Now %hash contains the data for the last record processed; however, data 
from any previous records have been obliterated.



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




The module Data::Dumper can help you see what's in your hash, but you 
need to rethink how you initialize the first hash (%hash).



--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: accesing a hash of an array of hashes

2007-05-26 Thread Paul Lalli
On May 26, 1:51 pm, [EMAIL PROTECTED] (Mumia W.)
wrote:
> On 05/26/2007 07:17 AM, 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])
> > and then
>
> > for (my $j=1;$j<$#rows;$j++)
> > {
> > my $status  = $csv->parse ($rows[$j]);   # parse a CSV string into
> > fields
>
> You don't check $status to see if the parse succeeded.
>
> > my @columns = $csv->fields ();   # get the parsed fields
>
> > for (my $i=0;$i<$#columns;$i++)
> >   {$hash{$headings[$i]}=$columns[$i];}
>
> Now %hash contains the data for the last record processed; however, data
> from any previous records have been obliterated.
>
> > 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
>
> The module Data::Dumper can help you see what's in your hash, but you
> need to rethink how you initialize the first hash (%hash).

So long as the OP declares his %hash in the for loop, there's nothing
wrong with how it's initialized.  The OP did not show where he's
declaring it, unfortunately.  If he made the mistake of declaring it
outside the for loop, then he's adding multiple copies of the same
hash to the array, and that single hash is going to be repeatedly
changed through the program.

Paul Lalli


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: accesing a hash of an array of hashes

2007-05-28 Thread pauld
thanks for the help - im looking up hash slices - but id like to get
something that works and then i can add new ideas etc so im going to
leave it as it for the time being.

Data::Dumper has helped sort out where  an error is coming

#!/usr/bin/perl -w
use strict;
use warnings;
open O, "<$file" or die "could not open $file - $!";
undef $/;
my $whole_file = ;
close O;
$whole_file=~s/\x0D\x0A1/\x0D\x0AABC1/g;my @rows=split(/\x0D\x0AABC/,
$whole_file);
##splits in the correct place after looking at the CSV file with a
hex editor - ugly but it seems to work ATM##

my %hash;
my  @headings=split(/,/,$rows[0])
 for (my $j=1;$j<=2;$j++)
{
my @columns = $csv->fields ();

for (my $i=0;$i<=$#columns;$i++)  {$hash{$headings[$i]}=$columns[$i];}

print Dumper(%hash);
push (@{$Hofdates{$hash{OPDATE}}},\%hash);
print Dumper (%Hofdates);
}

and i get this output


#1st record

$VAR1 = 'STANTIME';
$VAR2 = '06:04';
$VAR3 = 'T3_AN2no';
$VAR4 = '';
$VAR5 = 'DESC3';
$VAR6 = '';
$VAR7 = 'T1_ANSNAME';
etc etc to the end
then

-01/10/2006---BROWN---
$VAR1 = '01/10/2006';
$VAR2 = [
  {
'STANTIME' => '06:04',
'T3_AN2no' => '',
'DESC3' => '',
'T1_ANSNAME' => 'SMITH',
'P3_STANDTIME' => '',
'T2_AN2name' => '',

 'CANCREASON' => '',
'RN2_NO' => '',
'T2_SUSDuty' => ''
  }
];

###2nd record from file
$VAR1 = 'STANTIME';
$VAR2 = '17:39';
$VAR3 = 'T3_AN2no';
$VAR4 = '';
$VAR5 = 'DESC3';
$VAR6 = '';

$VAR347 = 'CANCREASON';
$VAR348 = '';
$VAR349 = 'RN2_NO';
$VAR350 = '';
$VAR351 = 'T2_SUSDuty';
$VAR352 = '';

--01/10/2006---JONES--
$VAR1 = '01/10/2006';
$VAR2 = [
  {
'STANTIME' => '17:39',
'T3_AN2no' => '',
'DESC3' => '',
'T1_ANSNAME' => '',
'P3_STANDTIME' => '',
'P4_OPCS4_3' => '',
'STANDATE' => '01/10/2006',
'CANCREASON' => '',
'RN2_NO' => '',
'T2_SUSDuty' => ''
  },
  $VAR2->[0]
];
grenada tmp #

so its  pushing the second hash onto the array  and overwriting the
1st


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: accesing a hash of an array of hashes

2007-05-28 Thread Paul Lalli
On May 27, 4:37 pm, [EMAIL PROTECTED] (Pauld) wrote:
> thanks for the help - im looking up hash slices -

perldoc perldata

 Entire arrays (and slices of arrays and hashes) are denoted
 by '@', which works much like the word "these" or "those"
 does in English, in that it indicates multiple values are
 expected.

 @days   # ($days[0], $days[1],... $days[n])
 @days[3,4,5]# same as ($days[3],$days[4],$days[5])
 @days{'a','c'}  # same as ($days{'a'},$days{'c'})

> but id like to get
> something that works and then i can add new ideas etc so im going to
> leave it as it for the time being.
>
> Data::Dumper has helped sort out where  an error is coming
>
> #!/usr/bin/perl -w
> use strict;
> use warnings;
> open O, "<$file" or die "could not open $file - $!";
> undef $/;
> my $whole_file = ;
> close O;


> $whole_file=~s/\x0D\x0A1/\x0D\x0AABC1/g;my @rows=split(/\x0D\x0AABC/,
> $whole_file);
> ##splits in the correct place after looking at the CSV file with a
> hex editor - ugly but it seems to work ATM##

absolutely no idea what's making you think any of this is necessary.

> my %hash;
> my  @headings=split(/,/,$rows[0])
>  for (my $j=1;$j<=2;$j++)
> {
> my @columns = $csv->fields ();
>
> for (my $i=0;$i<=$#columns;$i++)  {$hash{$headings[$i]}=$columns[$i];}
>
> print Dumper(%hash);
> push (@{$Hofdates{$hash{OPDATE}}},\%hash);
> print Dumper (%Hofdates);
>
> }
>



> so its  pushing the second hash onto the array  and overwriting the
> 1st

No kidding.  Did  you read my reply?  That's exactly what I said would
happen.  Declare your hash in the smallest scope possible - inside the
(first) for loop.  That way, when each iteration of the for loop
starts, you get a brand new hash rather than reusing the same one.

If you don't understand what that means - move the 'my %hash;' line
from where it is to just before the 'my @columns = $csv->fields ();'
line.

Paul Lalli


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/




Re: accesing a hash of an array of hashes

2007-05-29 Thread Jenda Krynicky
From: pauld <[EMAIL PROTECTED]>
> 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])
> and then
> 
> for (my $j=1;$j<$#rows;$j++)
> {
> my $status  = $csv->parse ($rows[$j]);   # parse a CSV string into
> fields
> my @columns = $csv->fields ();   # get the parsed fields
> 
> for (my $i=0;$i<$#columns;$i++)
>   {$hash{$headings[$i]}=$columns[$i];}
> 
> I want to  process the data once its grouped by the date field present
> in $hash.

Maybe your task would be easier if you used DBI and DBD::CSV and use 
SQL to group the data the way you need them instead of loading the 
raw data and "hand-processing" them.

Jenda

= [EMAIL PROTECTED] === http://Jenda.Krynicky.cz =
When it comes to wine, women and song, wizards are allowed 
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/