我正在做一个小型数据挖掘项目,其中perl脚本从SQL数据库中获取信息并对其进行解析.数据由几个时间戳组成.我想知道在任何特定日期存在多少特定类型的时间戳.不幸的是,这是我的第一个perl脚本,而且当涉及到哈希和数组时,perl的性质令我感到困惑.
代码段:
my %values=();#A hash of the total values of each type of data of each day. #The key is the day, and each key stores an array of each of the values I need. my @proposal; #[drafted timestamp(0), submitted timestamp(1), attny approved timestamp(2),Organiziation approved timestamp(3), Other approval timestamp(4), Approved Timestamp(5)] while(@proposal=$sqlresults->fetchrow_array()){ #TODO: check to make sure proposal is valid #Increment the number of timestamps of each type on each particular date my $i; for($i=0;$i<=5;$i++) $values{$proposal[$i]}[$i]++; #Update rolling average of daily #TODO: To check total load, increment total load on all dates between attourney approve date and accepted date for($i=$proposal[1];$i<=$proposal[2];$i++) $values{$i}[6]++; }
我一直在for循环增加值中得到语法错误.另外,考虑到我正在使用严格和警告,当我在哈希中访问它们时,Perl会自动创建正确值的数组,还是我会到处都出现超出范围的错误?
谢谢你的帮助,扎克
错误:
for($i=0;$i<=5;$i++) $values{$proposal[$i]}[$i]++; for($i=$proposal[1];$i<=$proposal[2];$i++) $values{$i}[6]++;
Perl不支持裸循环/条件块.或者更确切地说,它确实如此,但不是这样的.这可能适用于PHP,但不适用于Perl.您需要将这些包含在块中:
for($i=0;$i<=5;$i++) { $values{$proposal[$i]}[$i]++; } for($i=$proposal[1];$i<=$proposal[2];$i++) { $values{$i}[6]++; }
$values{$proposal[$i]}[$i]++;
由于Perl中的哈希只能在其中包含标量数据类型,为了将整个数组存储在哈希中,我们将不得不通过引用来完成它.这是一个关于数组引用的快速教程:
my $arr_ref = []; # empty array reference my $arr_ref = [ 1, 2, 'foo', ]; # initialize with values my $arr_ref = \@arr; # reference an existing array; # does not make copy, but provides a # read-write handle to the array $arr_ref->[0]; # index the first (index 0) element of the array @{$arr_ref}[ 0 .. 4 ]; # index elements number one through five (0-4) of the array # through what's called an "array slice"
上面的代码所做的是将哈希键的值从哈希中拉$proposal[$i]
出来%values
,然后将它(标量)用作数组(它不是数组).
正如我之前所说,您可以将它用作数组引用但不能用于数组:
# v-- note the arrow $values{$proposal[$i]}->[$i]++;
建议:
写作my $foo; for ($foo = 0; $foo <= 5; $foo++)
更容易写成" for my $foo (0 .. 5)
"或" foreach my $foo (0 .. 5)
".这实质上是大多数人这样做的.的注意的是,for
和foreach
是可以互换的,它的偏好和易读性的问题.
为了便于阅读,请使用多个空格缩进代码.一个好的经验法则是四个空格或一个标签.St. Larry Wall在设计Perl时考虑过人们说和写的语言.
我建议研究正确的(适当的,这里,意思是最有效的)写for
循环的方法.如果有很多长for
循环,有一些习惯会导致整体程序更快.例如:
++$foo
效率比$foo++
.这源于内部:
$foo++
递增变量,从中减去1,然后返回结果,而
++$foo
递增变量并返回它.更少的操作=更快.
小于或等于比较的效率低于普通小于比较.同样,这是由于计算机必须执行的操作数量.for ($x=0; $x<=5; ++$x)
写得更好for ($x=0; $x<6; ++$x)
.
Perl有一些很棒的循环控件.有些map
人非常强大.