2014-02-25 89 views
3

我只是学习perl。Perl哈希散列解引用

我想重写使用临时变量这个多层次循环,使我不需要以前的密钥($key1$key2)获得对$key3接入(解引用)。这将是最简单的方法。谢谢。

for my $key1 (keys %foo) 
{ 
    for my $key2 (keys %{$foo{$key1}}) 
    { 
     for my $key3 (keys %{$foo{$key1}{$key2}}) 
+0

如果你的数据结构变得太复杂,您可以考虑[使用OOP(http://perldoc.perl.org/perlootut.html) 。 – ThisSuitIsBlackNot

+1

如果您正在学习perl和数据结构,必须阅读的是[Perl参考教程](http://perldoc.perl.org/perlreftut.html),随后是[Perl Data Structures Cookbook](http:///perldoc.perl.org/perldsc.html)。它谈论你的情况等等。对于数组数组,请查看有趣的['perllol'](http://perldoc.perl.org/perllol.html)(Perl列表列表)。 –

回答

4

您正在寻找这样的事情:

for my $key1 (keys %foo) 
{ 
    my $subhash = $foo{$key1}; 
    for my $key2 (keys %$subhash) 
    { 
     my $subsubhash = $subhash->{$key2}; 
     for my $key3 (keys %$subsubhash) 
5

您可以使用whileeach这样的:

while (my ($key1, $inner_hash) = each %foo) { 

    while (my ($key2, $inner_inner_hash) = each %$inner_hash) { 

     while (my ($key3, $value) = each %$inner_inner_hash) { 
      print $value; 
     } 
    } 
} 

这种方法使用较少的内存比foreach keys %hash,它构造了一个开始迭代之前,散列中所有键的列表。 each的缺点是您无法指定排序顺序。详细信息请参见documentation

+0

我不清楚'each'是什么意思,使用的内存比'for'少。两者都是迭代器,但'for'在散列上并不是很有用,除非将它应用于散列的'keys'或'values',在这种情况下,它们之间几乎没有选择。 – Borodin

+0

啊,你是否认为'for(keys%hash){...}'首先从哈希键生成一个新数组?我没有想到,但似乎不太可能。我要去试验。 – Borodin

+0

@Borodin是的,我应该更清楚。在您开始迭代之前,'keys%hash'会生成所有键的列表; '每个%哈希'不。 – ThisSuitIsBlackNot

2

如何:

foreach(values %foo){ 
    foreach(values %$_){ 
    foreach my $key3 (keys %$_){ 
     print $key3; 
    } 
    } 
} 
1

我只是学习的Perl。

而你已经在做参考。这很好。

我想重写这个多级循环使用临时变量,以便我不需要以前的键($ key1 $ key2)获得访问(取消引用)$ key3。这将是最简单的方法。

如果我想我明白你在说什么,你希望能够找到所有的第三级散列键,而无需通过所有的第一和第二级散列键。

假设%foo有键:

$foo{one}->{alpha}->{apple}; 
$foo{one}->{alpha}->{berry}; 
$foo{one}->{beta}->{cucumber}; 
$foo{one}->{beta}->{durian}; 
$foo{two}->{uno}->{eggplant}; 
$foo{two}->{uno}->{fig}; 
$foo{two}->{dos}->{guava}; 
$foo{two}->{dos}->{honeydew}; 

顺便说一句,我喜欢->语法简单,因为它让我想起了我处理,并引用的东西不是一个实际的哈希值。这有助于我看到问题更清楚。

你想通过蔬菜和水果名称的关键没有通过前两个级别。那是对的吗?

这里的->语法有助于澄清答案。这八个键属于四个不同的哈希值:

$foo{one}->{alpha}; 
$foo{one}->{beta}; 
$foo{two}->{uno}; 
$foo{two}->{dos}; 

而且,他们所在的散列匿名,这是有它包含这些哈希没有变量名。我可以访问这些散列的唯一方法是找到包含它们的四个散列。

但是,这四个密钥本身存储在两个单独的哈希中。我需要找到这两个哈希来找到他们的钥匙。再次,这两个哈希是匿名。同样,我可以找到它们的唯一方法是要知道它们包含两个散列:

$foo{one}; 
$foo{two}; 

因此,为了寻找我的第三个层次的价值观,我需要知道包含它们的第二级哈希值。为了找到第二个哈希值,我需要找到包含它们的第一级密钥。然而,如果你有某种已知的结构,你可能已经知道你需要的键来找到你正在寻找的值。直接通过到第一,最后和中间每个人的初始

$person{$ssn}->{NAME}->{FIRST} = "Bob"; 
$person{$ssn}->{NAME}->{MI} = "Q."; 
$person{$ssn}->{NAME}->{LAST} = "Smith"; 

在这里,我可以去:

想象这样的事情。所有我需要做的就是经过不同的社会安全号码:

for my $ssn (sort keys %person) { 
    say "My name is " . $person{$ssn}->{NAME}->{FIRST} 
     . " " . $person{$ssn}->{NAME}->{MI} 
     . " " . $person{$ssn}->{NAME}->{LAST}; 
}