2015-12-28 63 views
0

可以說我有一個返回哈希結果的子例程。我想迭代來自父目錄中子例程的鍵/值對,並且不想將結果保存到變量中。簡單的perl迭代通過一行中的子例程返回的哈希?

這看起來很簡單,但我不知道如何去做。如果方法返回散列,我不知道告訴循環期望從方法返回散列的語法。如果該方法返回一個hashref我可以做

while(my($key,$value) = each (%{ generate_hash() }) 

但這重新運行generate_hash()方法中的每個時間循環完成後,再生相同的散列,並再處理的散列的所述第一元件(或至少它在5.10確實5.14允許每個採取可能解決這個問題,不知道一個標量,但我限制在5.10黯然。

誰能解釋我缺少什麼荒謬明顯的語法在這裏?

+5

「和不喜歡先保存結果的變量。」這實際上是降低代碼可讀性的一個不好的理由。 – ThisSuitIsBlackNot

+0

我不確定您可以在指定的限制範圍內執行此操作。要迭代一個散列,你真的需要'keys'或'each',在這兩種情況下你都需要'訪問'散列兩次。 (我想你可以在一次迭代中迭代一個元素,但是你仍然需要使用var來再次將它們粘在一起) – Sobrique

回答

2
use List::Util 1.29 'pairs'; 

for my $kv (pairs %{ genHash() }) { 
    my ($key, $value) = @$kv; 
    ... 
} 
0

隨着免責聲明評論者是正確的,這是一個壞主意,你可以

  1. 將作業放入%{...}劇組中。還不如讀,不會使代碼更簡潔,除非你可以更早的一個結合my聲明:

    my $foo; 
    while (my ($k,$v) = each %{$foo //= generate_hash}) { ... } 
    
  2. 確保generate_hash返回每次調用時相同的散列的引用。這樣,與哈希關聯的迭代器將被重用並給你一個新的密鑰。當然,要做到這一點最簡單的方法是用一個變量:

    my $cached_generated_hash; 
    sub generate_hash { 
        return $cached_generated_hash //= do { 
         ... 
         { abc => 123, def => 456 } 
        }; 
    } 
    
0

與@mob同意&提意見時,提出只爲娛樂下面。看起來沒有什麼效果,但我會感興趣的是,如果任何人都可以像一個「荒謬簡單的語法」那樣抽出一些東西來做到這一點:-)

哦,是的,請注意單一調用genHash()。

$ ./foo.pl 
Hello from genHash() 
a=beta 
a=2 
a=alpha 
a=1 
a=gamma 
a=3 

$ cat ./foo.pl 
#!/usr/bin/perl 

use strict; 

sub genHash() { 
    print "Hello from genHash()\n"; 
    return { alpha => 1, beta => 2, gamma => 3 }; 
} 

# There comes a point when you have to ask 
# why you are even trying to swim upstream :-) 
# ----- edit as per comments to remove unnecessary reference. 
# original: foreach my $a (%${ \(genHash()) }) { 
# ------------------------------ 
foreach my $x (%{ genHash() }) { 
    print "x=", $x, "\n"; 
} 

$ 
+0

沒有必要引用並立即解除引用,「foreach my $ foo(%{genHash()}){...}'給出了相同的結果。請注意,您不應將'$ a'或'$ b'詞彙化,因爲它們是爲'sort'保留的。 – ThisSuitIsBlackNot

+0

酷 - 謝謝,@ThisSuitIsBlackNot - 相應地編輯。我常常使用%$ someref,並不認爲只用%{genHash()}來嘗試 – jgreve