除了像其他人所建议的那样使用Text :: CSV,为了好玩,我已经重写了代码,因为我可能已经写了它。它包含了很多这里提出的建议以及我的一些个人风格选择。如果您有任何疑问,请询问。此外,如果您可以发布一些示例数据,我可以检查它是否有效。
#!/usr/bin/env perl
use strict;
use warnings;
my $lowestBirthRates = 100000000;
my $highestBirthRates = 0;
my $filename = 'census2008.txt';
open (my $fh, '<', $filename) or die "Cannot open $filename: $!";
my %data;
while (<$fh>) {
chomp;
my ($sumlev, $stname,$ctyname,$popestimate2008,$births2008,$deaths2008) = split(",");
push (@{$data{SumLev}}, $sumlev);
push (@{$data{StName}}, $stname);
push (@{$data{CtyName}}, $ctyname);
push (@{$data{PopEstimate}}, $popestimate2008);
push (@{$data{Births}}, $births2008);
push (@{$data{Deaths}}, $deaths2008);
}
my $i = 0;
my $size = @{$data{Births}};
while ($i < $size) {
if ($data{SumLev}[$i] eq " 040"){
#if ($data{SumLev}[$i] == 40){
my $temp = $data{Births}[$i]/$data{PopEstimate}[$i]/541;
if($lowestBirthRates > $temp && $temp > 0){
$lowestBirthRates = $temp;
}
if ($highestBirthRates < $temp){
$highestBirthRates = $temp;
}
}
$i++;
}
print <<REPORT;
Lowest birth rate in LOW-STATE: $lowestBirthRates per 541
Highest birth rate in HIGH-STATE: $highestBirthRates per 541
In Washington:
Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541
Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541
REPORT
,如果您有有Perl版本5.14或更高版本安装的奢侈,你可以使用一个更清晰的语法,其中push
可直接乘坐引用,并在each
可以给所关注的索引以及价值。
#!/usr/bin/env perl
use strict;
use warnings;
use 5.14.0;
my $lowestBirthRates = 100000000;
my $highestBirthRates = 0;
my $filename = 'census2008.txt';
open (my $fh, '<', $filename) or die "Cannot open $filename: $!";
my %data = (
SumLev => [],
StName => [],
CtyName => [],
PopEstimate => [],
Births => [],
Deaths => [],
);
while (<$fh>) {
chomp;
my ($sumlev, $stname,$ctyname,$popestimate2008,$births2008,$deaths2008) = split(",");
push ($data{SumLev}, $sumlev);
push ($data{StName}, $stname);
push ($data{CtyName}, $ctyname);
push ($data{PopEstimate}, $popestimate2008);
push ($data{Births}, $births2008);
push ($data{Deaths}, $deaths2008);
}
while (my ($i, $births) = each $data{Births}) {
if ($data{SumLev}[$i] eq " 040"){
#if ($data{SumLev}[$i] == 40){
my $temp = $births/$data{PopEstimate}[$i]/541;
if($lowestBirthRates > $temp && $temp > 0){
$lowestBirthRates = $temp;
}
if ($highestBirthRates < $temp){
$highestBirthRates = $temp;
}
}
}
print <<REPORT;
Lowest birth rate in LOW-STATE: $lowestBirthRates per 541
Highest birth rate in HIGH-STATE: $highestBirthRates per 541
In Washington:
Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541
Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541
REPORT
最后这里是使用Tie::Array::CSV
一个实现我写信给能够使用CSV文件,就像在Perl的2D阵列(即ArrayRefs的阵列)。它使用Text::CSV
进行分析,并使用Tie::File
进行线路访问。这意味着您不需要像前面的例子那样将所有数据存储在内存中。
#!/usr/bin/env perl
use strict;
use warnings;
use Tie::Array::CSV;
my $lowestBirthRates = 100000000;
my $highestBirthRates = 0;
my $filename = 'census2008.txt';
tie my @data, 'Tie::Array::CSV', $filename
or die "Cannot tie $filename: $!";
foreach my $row (@data) {
my ($sumlev, $stname, $ctyname, $popest, $births, $deaths) = @$row;
if ($sumlev eq " 040"){
#if ($sumlev == 40){
my $temp = $births/$popest/541;
if($lowestBirthRates > $temp && $temp > 0){
$lowestBirthRates = $temp;
}
if ($highestBirthRates < $temp){
$highestBirthRates = $temp;
}
}
}
print <<REPORT;
Lowest birth rate in LOW-STATE: $lowestBirthRates per 541
Highest birth rate in HIGH-STATE: $highestBirthRates per 541
In Washington:
Lowest birth rate in LOW-COUNTY County, WA: x.xxx per 541
Highest birth rate in HIGH-COUNTY County, WA: x.xxx per 541
REPORT
**总是**用'use strict;启动一个Perl程序;使用警告;'当你打开一个文件时,测试一下你是否成功了perl [perldoc中的示例](http://perldoc.perl.org/functions/open.html)。 – Quentin
并且不要推出自己的CSV解析器,使用[Text :: CSV](https://metacpan.org/module/Text::CSV),它更快,并且处理大量的边缘情况。 – Quentin
@Quentin:原则上我同意'Text :: CSV'的建议,但看起来OP在使用模块之前还有很长的路要走。这是学习曲线的一部分 – Zaid