3

これは私が取り組んでいるコードスニペットです:

my %photo_details = (
 'black_cat' => (
  ('size' => '1600x1200', 'position' => -25),
  ('size' => '1280x1024', 'position' =>  25),
  ('size' =>   '800x600', 'position' =>   0),
 ),
 'race_car' => (
  ('size' => '1600x1200', 'position' =>  10),
  ('size' =>   '800x600', 'position' =>   5),
 ),
);

my $photo = 'black_cat';

foreach my $photo_detail ($photo_details{$photo})
{
 my $size     = $photo_detail{'size'};
 my $position = $photo_detail{'position'};

 print ("size = $size, position = $position\n");
}

私が期待しているのは次のとおりです。

サイズ = 1600x1200、位置 = -25

サイズ = 1280x1024、位置 = 25

サイズ = 800x600、位置 = 0

私が得るものは次のとおりです。

C:\Test.pl 行 23 の連結 (.) または文字列で、初期化されていない値 $size が使用されています。

C:\Test.pl 行 23 の連結 (.) または文字列で、初期化されていない値の $position が使用されています。

サイズ = 、位置 =

$size と $position の値がないだけでなく、ループを 3 回ではなく 1 回しか通過していないため、foreach ステートメントは明らかに間違っています。変数プレフィックスのあらゆる種類のバリアントを試しましたが、機能するものはありませんでした。

私は何を間違っていますか?

4

3 に答える 3

14

以下に、いくつかの更新されたコードとその説明を示します。

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my %photo_details = (
    'black_cat' => [
        {'size' => '1600x1200', 'position' => -25},
        {'size' => '1280x1024', 'position' =>  25},
        {'size' =>   '800x600', 'position' =>   0},
    ],
    'race_car' => [
        {'size' => '1600x1200', 'position' =>  10},
        {'size' =>   '800x600', 'position' =>   5},
    ],
);


print Dumper( %photo_details );
foreach my $name ( keys %photo_details ) {
    foreach my $photo_detail ( @{ $photo_details{$name} } ) {
        my $size     = $photo_detail->{'size'};
        my $position = $photo_detail->{'position'};

        print Dumper( $photo_details{$photo} );

        print ("size = $size, position = $position\n");
    }
}

括弧の一部を角括弧と中括弧に置き換えました。Perl では、角括弧は無名配列への参照を示し、中括弧は無名ハッシュへの参照を示します。匿名配列またはハッシュには明示的な変数名がないため、これらは匿名と呼ばれます。

Perl のデータ構造では、実際のハッシュではなくハッシュへの参照を格納するため、参照を構築するにはこれらが必要です。これは、次のように 2 つの手順で実行できます。

my @array = ( 1, 2, 3 );
my $array_ref = \@array;
my %hash = ( 'one' => 1, 'two' => 2, 'three' => 3 );
my $hash_ref = \%hash_ref;

$array_ref と $hash_ref からデータを取得するには、-> 演算子が必要です。

print $array_ref->[0], "\n";
print $hash_ref->{one}, "\n";

ハッシュ キーを参照する場合、{} 内に引用符を付ける必要はありませんが、ハッシュ キーを引用符で囲むことをお勧めする人もいます。

1 つの参照だけを見るのではなく、データ構造全体に対する反復の例を例として追加しました。最初の行は次のとおりです。

foreach my $name ( keys %photo_details ) {

keys メソッドはすべてのキーをハッシュで返すので、キーを順番に取得できます。次の行は、%photo_details 内のすべての photo_detail ハッシュリファレンスを繰り返します。

    foreach my $photo_detail ( @{ $photo_details{$photo} } ) {

@{ $photo_details{$photo} }参照$photo_details{$photo}を配列に逆参照します。これを foreach で反復処理できます。

最後に追加したのはData::Dumperへの呼び出しです。これは Perl と共に配布される非常に便利なモジュールで、データ構造を出力します。これは、このようなデータ構造を構築するときに非常に便利です。これは、密接に関連したData::Dumper::Simpleと同様です。残念ながら、このモジュールは Perl と一緒に配布されていませんが、変数名が含まれているため、出力を好みます。

参照を使用して複雑なデータ構造を構築する方法についてさらに読むには、perlreftutを調べてください。

于 2010-01-03T04:24:11.510 に答える
14

まず第一に、常にすべてのスクリプトまたはモジュールを次のように開始します。

use strict;
use warnings;

より多くの警告メッセージがより早く表示されるため、デバッグに非常に役立ちます。

あなたのエラーを複製することはできません。そのコードをファイルに入れ、追加のフラグなしで実行すると、次のようになります: size = , position =. 出力したコードには変数がない$sizeため、エラー メッセージは一致しません。

それにもかかわらず、データ構造を正しく宣言していません。ハッシュと配列には、リストではなくスカラー値のみを含めることができます。したがって、配列またはハッシュをネストする場合は、それを参照にする必要があります。データ構造と参照の詳細については、 perldoc perldataperldoc perldsc およびperldoc perlreftutを参照してください。

my %photo_details = (
    black_cat => [
        { size => '1600x1200', position => -25 },
        { size => '1280x1024', position =>  25 },
        { size => '800x600', position => 0 },
    ],
    race_car => [
        { size => '1600x1200', position =>  10 },
        { size => '800x600', position =>   5 },
    ],  
);

foreach my $photo_detail (@{$photo_details{black_cat}})
{
    my $size     = $photo_detail->{size};
    my $position = $photo_detail->{position};

    print ("size = $size, position = $position\n");
}
于 2010-01-03T03:03:02.147 に答える
2

気にしなければならないことは 1 つだけです。それは、データ構造の最上位レベルです。その後、各レベルに適切なインデックス構文を使用するだけです。

通常のハッシュがある場合は、必要なキーにアクセスし、その後に各レベルの追加のインデックスを並べます。

 %regular_hash = ...;
 $regular_hash{$key}[$index]{$key2};

参照がある場合は、ほぼ同じことを行いますが->、トップレベルの参照の後に矢印 , を使用して最初の逆参照から始める必要があります。その後は、同じインデックス シーケンスです。

 $hash_ref = ...;
 $hash_ref->{$key}[$index]{$key2};

すべての詳細については、参照構文について説明しているIntermediate Perlを参照してください。

于 2010-01-03T10:08:43.497 に答える