2014-02-25 127 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}; 
}