1

Perl でハッシュ内にハッシュの構造を作成したいのですが、すべてのチュートリアル (章 9.4. Perl のプログラミングにおけるハッシュのハッシュ など) では、それらがすべて事前に追加されています。最初に構造を作成し、ファイルの読み取り中にサブルーチンを使用して空のハッシュを埋めたいと思います。

たとえば、本を読みたいのですが、ページごとに単語とそのページのどの行に表示されたかを追跡します。

次の構造:

%Parent = (
    1 => {
        "the" => [1, 4],
        "and" => [2, 3]
    },
    2 => {
        "but" => [1, 2],
        "as"  => [3, 4]
    }
)

theは、単語が 1 ページの 1 行目と 4 行目にbut表示され、2 ページ目の 1 行目と 2 行目に表示される、などを意味します。

これどうやってするの?私がそれをやろうとするたびに、ハッシュを保持できないようで、値を失っていました。

4

3 に答える 3

4
"the" => (1, 4), "and" => (2, 3)

変な書き方です

"the", 1, 4, "and", 2, 3

ハッシュに割り当てられた場合、これは次と同等になります

%h = ();
$h{"the"} = 1;
$h{4} = "and";
$h{2} = 3;

あなたがしたい

%Parent = (
    1 => {
        "the" => [ 1, 4 ],
        "and" => [ 2, 3 ]
    },
    2 => {
        "but" => [ 1, 2 ],
        "as"  => [ 3, 4 ]
    }
)

{ }ハッシュを作成し、内部式 (存在する場合) の結果をハッシュに代入し、そのハッシュへの参照を返し、[ ]配列を作成し、内部式 (存在する場合) の結果を配列に代入し、返すのと同じようにその配列への参照。


もちろん、どれもあなたの質問に答えません! あなたの質問に。

my %Parent = (
    1 => {
        "the" => [1, 4],
        "and" => [2, 3]
    },
    2 => {
        "but" => [1, 2],
        "as"  => [3, 4]
    }
);

基本的に同等です

my %Parent;
$Parent{1}{the}[0] = 1;
$Parent{1}{the}[1] = 4;
$Parent{1}{and}[0] = 2;
$Parent{1}{and}[1] = 3;
$Parent{2}{but}[0] = 1;
$Parent{2}{but}[1] = 2;
$Parent{2}{as }[0] = 3;
$Parent{2}{as }[1] = 4;

push多くの場合、配列を設定するための代入よりも便利です。それは次のようになります。

my %Parent;
push @{ $Parent{1}{the} }, 1;
push @{ $Parent{1}{the} }, 4;
push @{ $Parent{1}{and} }, 2;
push @{ $Parent{1}{and} }, 3;
push @{ $Parent{2}{but} }, 1;
push @{ $Parent{2}{but} }, 2;
push @{ $Parent{2}{as } }, 3;
push @{ $Parent{2}{as } }, 4;

自動活性化のおかげで、

push @{ $Parent{$k1}{$k2} }, $n;

の略です

push @{ ( $Parent{$k1} //= {} )->{$k2} //= [] }, $n;
于 2012-07-09T20:04:51.103 に答える
3

間違いは、第 2 レベルのハッシュの単語キーにリスト式を割り当てることです。これは、代わりに arrayref でなければなりません"the" => [1, 4]

# assume $page, $line defined
for my $word (@words) {
    push @{ $Parent{$page}{$word} }, $line;
}
于 2012-07-09T19:54:22.753 に答える
0

最初に $Parent を var として初期化します。

my $Parent; # we will use this to store ref of parsed hash 

$page にページ番号、$word に単語、$line に行を保存しているとします。新しい行番号を保存する場合はいつでもファイルを解析しながら、次のようなコードを使用できます。

if(exists $Parent->{$page} and $Parent->{$page}->{$word}){
  push( @{ $Parent->{$page}->{$word} },$line);
}else{
  $Parent->{$page}->{$word} = [$line];
}

ここで、$Parent->{$page}->{$word} がまだ初期化されていない場合は、最初に匿名配列で初期化するようにしています。存在する場合は、行番号をそこにプッシュします。

于 2012-07-14T12:08:03.533 に答える