1

我想在 Perl 的散列中创建一个散列结构,但是所有教程(如第 9.4 章。编程 Perl的散列的散列)都预先添加了它们。我想最初创建结构,然后在读取文件时使用子例程填充空哈希。

例如,我想在一本书中阅读,并为每一页跟踪单词以及它们出现在页面中的哪些行。

以下结构:

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

表示单词the出现在第 1 页的第 1 行和第 4but行,出现在第 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

错误在于将列表表达式分配给二级哈希中的单词键。这必须是一个数组引用,例如"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 中存储 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 回答