Eek! I can't believe that no one metioned DBD::CSV.
I see two answers that are using different arrays to
store the data - why not just use a 2-d array?
my (%fields,@records);
@fields{qw(lastname firstname age height weight)} = (0..4);
while(<DATA>) {
chomp;
my @row = split(/,/,$_);
push @records, \@row;
}
__DATA__
Smith,Joe,40,76,175
Page,Betty,60,58,165
Nader,Ralph,55,63,190
Alexander,Sue,25,54,98
Saxon,Jackson,32,60,155
Now you can write a subroutine that will sort the 2-d array
and you can use %fields to reference the field by a name
rather than a number.
But your subroutine should be smart enought to know the
when to do a numerical sort ({ $a <=> $b }) and
when to do an 'ASCII' sort ( { $a cmp $b }).
It should also be smart enought to sort ascending ($a before $b)
and descending ($b before $a).
You could do that, or you could use DBD::CSV:
use DBI;
use Text::CSV_XS; # or your other favorite CSV module
my $CSV = new Text::CSV_XS;
my $DBH = DBI->connect("DBI:CSV:");
$DBH->{RaiseError} = 1;
$DBH->do("
create table info(
lname char(20), fname char(20),
age integer, height integer, weight integer
)
");
# i am still new to DBD::CSV, i am sure there is a way
# to eliminate this while loop, i'll be researching...
# in the meantime, we can use Text::CSV_XS . . .
while (<DATA>) {
chomp;
$CSV->parse($_) or next;
my $sth = $DBH->prepare("
insert into info
values(?,?,?,?,?)
");
$sth->execute($CSV->fields);
}
my $sth = $DBH->selectall_arrayref("
select *
from info
order by lname desc, fname asc
");
foreach (@$sth) {
print join("\t", @$_), "\n";
}
# very mandatory to drop the table explicitly
# if you wish to run this program more than once
$DBH->do("drop table info");
__DATA__
Smith,Joe,40,76,175
Page,Betty,60,58,165
Nader,Ralph,55,63,190
Alexander,Sue,25,54,98
Saxon,Jackson,32,60,155
this will produce:
Smith Jane 30 57 113
Smith Joe 40 76 175
Saxon Jackson 32 60 155
Page Betty 60 58 165
Nader Ralph 55 63 190
Alexander Sue 25 54 98
Jeff
R-R-R--R-R-R--R-R-R--R-R-R--R-R-R--
L-L--L-L--L-L--L-L--L-L--L-L--L-L--
|