2011-07-12 4 views
2

こんにちは私はクラス名、登録された学生の数と学生の名前を含むハッシュのハッシュを持っています。
2番目のレベルのキーを繰り返さずにこのハッシュを印刷するにはどうすればよいですか。
例:私のハッシュに記入したデータはScienceクラスです.3人の学生がGeorge、Lisa、Mathias and Math Classに登録し、4人の学生がPeter、George、Anna、Martinに登録しました。第2レベルのキーを繰り返さずに複雑なハッシュを印刷するにはどうすればいいですか?

Science_class:2 =リサ
1 =ジョージ
3 =マティアス
Math_class:2 =アンナ
1 =マーティン
3 =ピーター

my %register=(); 

$register{$className}->{$count_students}=$student_name; # Fill the hash. 

    foreach my $key (keys %register){  

    print "$key: "; 

    foreach my $class (keys %{ $register{$key} }){ 

     print "$class=$register{$key}->{$class}\n"; 

    } 
} 

は、私のようになり得ます4 =ジョージ

しかし私の結果は次のようになります:

Science_class:3 - >リサ、ジョージ、マティアス
Math_class:4 - >アンナ、マーティン、ピーター、ジョージ

私は私のスクリプトを修正するにはどうすればよいですか?私を助けてください。

+0

クラスごとに複数の '$のcount_students'はあります(つまり、 1つ以上の科学クラス)? – Jon

+0

私はあなたの質問を理解していますが、Science Math Englishのような複数のクラスがあります。 – user831579

答えて

5

あなたがスカラーコンテキストでkeys機能を有する第二のレベルのエントリ数を取得することができますし、あなただけの値を取得することができます:名前を表示するための内部ループを持ってする必要はありません、ただキーを使用第2レベルではvalues機能を使用します。

#!/usr/bin/perl 

use strict; 
use warnings; 

my %register = (
    Science_class => { 
     1 => "George", 
     2 => "Lisa", 
     3 => "Mathias", 
    }, 
    Math_class => { 
     1 => "Martin", 
     2 => "Anna", 
     3 => "Peter", 
     4 => "George", 
    } 
); 

for my $class (keys %register) { 
    print "$class: ", scalar keys %{$register{$class}}, 
     " ", join(", ", values %{$register{$class}}), "\n"; 
} 

しかし、あなたのデータの構造を考えると、配列リファレンスのハッシュは、より理にかなって:

#!/usr/bin/perl 

use strict; 
use warnings; 

my %register = (
    Science_class => [ 
     "George", 
     "Lisa", 
     "Mathias", 
    ], 
    Math_class => [ 
     "Martin", 
     "Anna", 
     "Peter", 
     "George", 
    ] 
); 

for my $class (keys %register) { 
    print "$class: ", scalar @{$register{$class}}, 
     " ", join(", ", @{$register{$class}}), "\n"; 
} 

あなたが作成したPerl 5のデータ構造を操作する方法を理解する上で有益なperldoc perldscを読んで見つけることがあります。

2

スカラーコンテキストでは、キーはハッシュ内のキーの数を返します。配列コンテキストでは、それらのキーの配列を返します。内側のループを入力する前にクラスの名前の後にそのクラスの生徒の数を表示して、その番号を複数回出力しないようにしたいとします。

$numkeys = keys $register{$key}; 
print "$key: $numkeys ->"; 

この配列の名前が続きます。

print join(", ", keys $register{$key}); 
1

各クラスには生徒の数を記憶する必要はありません。これは、あなたがそのクラスの生徒の数を数えればよいからです。 (したがって、あなたのカウントがあなたの構造が変化したときに同期しなく取得することはできません。)私はこのように、配列のハッシュを使用することをお勧めします:

use strict; 
use warnings; 

my %register; 

# populate the hash, e.g.: 
my $classname = 'science_class'; 
push @{ $register{$classname} }, 'Lisa'; 
push @{ $register{$classname} }, 'George'; 
push @{ $register{$classname} }, 'Mathias'; 

# print the results: 

foreach my $class(sort keys %register) { 
    print $class, ' : '; 
    my @students = @{ $register{$class}; 
    print scalar(@students), ' = '; # number of elements in the array 
    print join ', ', @students; 
    print "\n"; 
} 
関連する問題