简体   繁体   English

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

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

I'm doing a little datamining project where a perl script grabs info from a SQL database and parses it. 我正在做一个数据挖掘项目,其中一个perl脚本从SQL数据库中获取信息并进行解析。 The data consists of several timestamps. 数据由几个时间戳组成。 I want to find how many of a particular type of timestamp exist on any particular day. 我想查找在任何特定日期存在多少种特定类型的时间戳。 Unfortunately, this is my first perl script, and the nature of perl when it comes to hashes and arrays is confusing me quite a bit. 不幸的是,这是我的第一个perl脚本,涉及哈希和数组时,perl的性质使我相当困惑。

Code segment: 代码段:

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]++; 
}

I keep getting syntax errors inside the for loops incrementing values. 我不断在for循环中增加值的语法错误。 Also, considering that I'm using strict and warnings, will Perl auto-create arrays of the right values when I'm accessing them inside the hash, or will I get out-of bounds errors everywhere? 另外,考虑到我正在使用严格警告,Perl在散列中访问它们时会自动创建正确值的数组,还是会遍地出界错误?

Thanks for any help, Zach 感谢您的帮助,扎克

Errors: 错误:

for($i=0;$i<=5;$i++)
    $values{$proposal[$i]}[$i]++;
for($i=$proposal[1];$i<=$proposal[2];$i++)
    $values{$i}[6]++; 

Perl does not support bare loop/conditional blocks. Perl不支持裸循环/条件块。 Or rather, it does , but not like this. 或更确切地说, 确实如此 ,但并非如此。 This may work in PHP, but not in Perl. 这可能在PHP中起作用,但在Perl中不起作用。 You will want to enclose these in blocks: 您将需要将它们包含在块中:

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]++;

Since hashes in Perl can only fit scalar data types in them, in order to store an entire array inside of a hash, we're going to have to do it by reference. 由于Perl中的哈希只能在其中容纳标量数据类型,因此为了将整个数组存储在哈希中,我们将不得不通过引用来实现。 Here's a quick tutorial on array references: 这是有关数组引用的快速教程:

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"

What your code above does is pull the value at hash key $proposal[$i] out of the hash %values , then use it (a scalar) as an array (it is not an array). 上面的代码所做的是从哈希%values取出哈希键$proposal[$i]%values ,然后将其(标量)用作数组(不是数组)。

As I said before, you can use it as an array reference but not an array: 如前所述,您可以将其用作数组引用,但不能用作数组:

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

Suggestions: 建议:

  • Writing my $foo; for ($foo = 0; $foo <= 5; $foo++) my $foo; for ($foo = 0; $foo <= 5; $foo++) my $foo; for ($foo = 0; $foo <= 5; $foo++) is more easily written as " for my $foo (0 .. 5) " or " foreach my $foo (0 .. 5) ". my $foo; for ($foo = 0; $foo <= 5; $foo++)更容易写为“ for my $foo (0 .. 5) ”或“ foreach my $foo (0 .. 5) ”。 This is, in essence how most people do it. 本质上,这就是大多数人的做法。 Of note is that for and foreach are interchangeable–it's a matter of preference and legibility. 值得注意的是forforeach是可互换的–这是偏好和易读性的问题。

  • Please, for legibility's sake, indent your code with more than one space. 出于可读性考虑,请将代码缩进多个空格。 A good rule of thumb is four spaces, or a tab. 一个好的经验法则是四个空格或一个制表符。 St. Larry Wall was thinking of languages people speak and write when he designed Perl. St. Larry Wall在设计Perl时就想到了人们会说和写的语言。

  • I'd recommend researching the proper (proper, here, meaning most efficient) way to write for loops. 我建议你研究的正确(正确的,在这里,意思是最有效的)的方式来写for循环。 There are a few habits that can result in faster programs overall if they have a lot of long for loops. 有迹象表明,可以加快程序的整体,如果他们有很多的长一些习惯for循环。 For instance: 例如:

    • ++$foo is more efficient than $foo++ . ++$foo$foo++更有效。 This stems from the internals: 这源于内部:
      • $foo++ increments the variable, subtracts 1 from it, then returns the result, whereas $foo++递增变量,从中减去1,然后返回结果,而
      • ++$foo increments the variable and returns it. ++$foo递增变量并返回它。 Fewer operations = faster. 更少的操作=更快。
    • A less-than-or-equals comparison is less efficient than a plain less-than comparison. 小于等于的比较比普通小于的比较效率低。 Again, this is due to the number of operations you computer has to perform. 同样,这是由于计算机必须执行的操作数量所致。 for ($x=0; $x<=5; ++$x) is better-written as for ($x=0; $x<6; ++$x) . for ($x=0; $x<=5; ++$x)的书写方式与for ($x=0; $x<6; ++$x)更好。
  • Perl has some wonderful loop controls. Perl有一些很棒的循环控件。 Some, like map , are very powerful. 有些功能(例如map )非常强大。

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

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