2013-11-05 14 views

回答

6

$seen{$_}++遞增$seen{$_}的值,並評估爲原始值。因此,在第一次看到給定值時,它的計算結果爲零(假),並且在隨後的每個時間都爲正值(真)。所以! $seen{$_}++是第一次看到給定的值,然後是錯誤的。

 

  1. 迂腐注:從技術上講,零不再是原來的值。原始值是'未定義'。但++在開始工作之前將undefined轉換爲零,並在完成時返回零。但是你實際上得到的結果是相同的,因爲undefined就是零,就像零。
+0

您的迂腐筆記也被稱爲autovivificaton? – squiguy

+1

@squiguy:不,只是後綴++運算符的一個有用的異常。 – ysth

+3

@squiguy:不,不完全。 「Autovivification」是指將未定義的參考視爲參考:即時創建必需的匿名對象。 「++」的功能非常相似,但沒有使用該術語。 (我認爲「autovivification」這個詞如此着名的主要原因是它有時是一件壞事:如果你在你寫'if($ foo - > {'bar'} - > {'baz'})'''意思是如果($ foo - > {'bar'} && $ foo - > {'bar'} - > {'baz'})',你可能永遠不會意識到你意外地改變了你的數據,看起來像一個只讀表達式,'++'顯然會突變數據,所以沒有問題。) – ruakh

1
my @unique = grep { ! $seen{ $_ }++ } @t_array; 

相當於

my @unique = grep { 

    # have we seen value of $_ yet? 
    my $not_seen_yet = ! $seen{ $_ }; 
    # increment hash value by 1 for $_ key 
    $seen{ $_ } += 1; 
    $not_seen_yet; 

} @t_array; 

++autoincrement操作者:

如果放置在變量之前,它們遞增或返回值之前遞減由一個可變,如果放在後面,則在返回值後遞增或遞減

+0

它們不完全等價,因爲'++'是神奇的。如果'@ t_array'中的'grep'和'a'之前有'$ seen {a} ='a';'$ seen {a}'是'1'而不是''b' '。雖然'@ unique'的內容仍然是相同的,所以它並不重要。 –

+0

@BradGilbert是的,但散列開始爲空'my%seen =();'所以散列值可以只是數字。 –

+0

感謝您提供的所有信息。 –