繁体   English   中英

新的Perl用户:使用数组哈希

[英]New Perl user: using a hash of arrays

我正在做一个数据挖掘项目,其中一个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"

上面的代码所做的是从哈希%values取出哈希键$proposal[$i]%values ,然后将其(标量)用作数组(不是数组)。

如前所述,您可以将其用作数组引用,但不能用作数组:

                    # v-- note the arrow
$values{$proposal[$i]}->[$i]++;

建议:

  • my $foo; for ($foo = 0; $foo <= 5; $foo++) my $foo; for ($foo = 0; $foo <= 5; $foo++)更容易写为“ for my $foo (0 .. 5) ”或“ foreach my $foo (0 .. 5) ”。 本质上,这就是大多数人的做法。 值得注意的是forforeach是可互换的–这是偏好和易读性的问题。

  • 出于可读性考虑,请将代码缩进多个空格。 一个好的经验法则是四个空格或一个制表符。 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 )非常强大。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM