2

私は、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ループ内で構文エラーが発生し続けます。また、strictとwarningsを使用していることを考えると、Perlはハッシュ内でそれらにアクセスするときに正しい値の配列を自動作成しますか、それともどこでも範囲外エラーが発生しますか?

助けてくれてありがとう、ザック

4

1 に答える 1

5

エラー:

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)forforeach

  • 読みやすくするために、コードを複数のスペースでインデントしてください。経験則として、4つのスペースまたはタブがあります。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に、非常に強力なものもあります。

于 2010-06-01T19:24:28.183 に答える