2013-04-17 30 views
9

我是perl初學者,我正在閱讀grep函數來過濾列表。我遇到了以下程序。

#!/usr/bin/perl 

use strict; 
use warnings; 

# initialize an array 
my @array = qw(3 4 5 6 7 8 9); 

# first syntax form: 
my @subArray = grep { $_ & 1 } @array; 

聲明my @subArray = grep { $_ & 1 } @array;回報奇數號碼@array。我不明白表達式($_ & 1)是如何工作的。我在谷歌搜索,但沒有找到任何有用的鏈接。

  • 那是什麼樣的特殊算子?

  • 是否有任何其他變種EXPR

在此先感謝。

+0

供參考:這是一個非常整齊劈**應從未在生產代碼中使用**除非發現僅奇數元素的動作基準爲性能瓶頸的更具可讀性的實現。 – DVK

+0

@DVK嗯,至於我的興趣:這個提示用過嗎? '$ _ || = $ val' – gaussblurinc

+0

@loldop - '|| ='操作符是完全正確的慣用Perl,不是黑客。然而,使用'$ _'而不是使用自編寫的命名變量往往是編寫不好的代碼的標誌,除非在非常短的'map' /'grep'塊中使用。 – DVK

回答

10

$_是變量保持當前測試值,&是二進制AND運算,並1只是一個數字。該表達式通過邏輯AND將$_1的所有位相互組合。所以如果該值爲奇數則返回1,如果該值爲偶數則返回0。例如,假設$ _是123,那麼它的二進制表示將是1111011。十進制數字1是00000001,因此,通過組合位,你會得到

123 = 1111011 
    1 = 0000001 
     - AND - 
     0000001 = 1 

又如200 & 100

200 = 11001000 
100 = 01100100 
     - AND -- 
     01000000 = 64 
+0

在第二個例子('200&100')中,答案是否是「64」或者我的轉換方式是錯誤的? –

+0

你說得對,那當然是64。 128是我的錯誤。 – tauli

1

$_是當前表達式。在這種情況下,每個數組元素。

&是二元AND運算符。

因此,總之,grep將匹配任何奇數數組元素。

使用$_grep記錄在perldoc中。 &的含義也在perldoc中。

2
grep{ $_ & 1} 

將在您的陣列中的每個元素走過去做1 逐位匹配這意味着grep的匹配,有一個1在去年(LSB)位的任何元素。 由於只有奇數具有1作爲LSB這將只返回奇數

& is the bitwise AND 
0

$_是grep的功能設置一個變量。如果未另行指定,大多數perl函數都會操作$ _。 Grep爲@array的每個元素調用定義的匿名子(即{ $_ & 1 }),並按位進行調用&。如果結果是真值,則將其添加到結果數組中。

4

正如很多人指出的那樣,&是按位運算符。這意味着,所比較的兩個數字都變成位和比較:

例如,3 & 1返回1,其評估爲真grep的內部:

Num | Bits 
----+----- 
    3 | 1 1 
& 1 | 0 1 
----+----- 
    1 | 0 1 <- result of 'and'ing each bit column 

同樣,4 & 1返回0,這是假:

Num | Bits 
----+------- 
    4 | 1 0 0 
& 1 | 0 0 1 
----+------- 
    0 | 0 0 0 <- all zeros because no column contains 1 & 1 

這就是說,一種替代方式過濾奇數是到mod用2數:

my @odd = grep { $_ % 2 } 1 .. 7; # 1, 3, 5, 7 
相關問題