2013-04-17 13 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; 

@arrayに奇数番号を返しmy @subArray = grep { $_ & 1 } @array;声明。表現($_ & 1)がどのように機能するのか分かりませんでした。私はGoogleで検索しましたが、役に立つリンクは見つかりませんでした。

  • これはどのような特殊演算子ですか?

  • EXPRは他にもありますか?

ありがとうございました。

+0

はFYI:のみ奇数の要素を見つけるの動作は、パフォーマンスのボトルネックであることをベンチマークされていない限り、これは**生産コードで使用すべきではありません非常に巧妙なハック**ですより読みやすい実装。 – DVK

+0

@DVK Hm、私の興味のために:このヒントは使われていますか? '$ _ || = $ val' – gaussblurinc

+0

@loldop - ' || = '演算子は完全に適切なイディオムのPerlであり、ハックではありません。しかし、 '$ _'をself-documentedly-named-variavleを使用するのではなく、非常に短い' map'/'grep'ブロックで使用しない限り、よく書かれていないコードの印です。 – DVK

答えて

10

$_として1を有するので、現在試験値、&を保持する変数をバイナリAND演算子であり、1ちょうどナンバーワンです。この式は、$_1のすべてのビットを論理積で結合します。したがって、値が奇数の場合は1を返し、偶数の場合は0を返します。

たとえば、$ _が123の場合、バイナリ表現は1111011となります。進数1は00000001だろう、そうですべてのビットを組み合わせて、あなたは

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

別の例200 & 100

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

2番目の例( '200&100')では、答えは' 64'ですか、私の変換方法は間違っていますか? –

+0

あなたは正しいです、それはもちろん64でなければなりません。 128は私のところでは誤りだった。 – tauli

1

$_が現在の式です。この場合、各配列要素。

&は、2進AND演算子です。

つまり、grepは、奇数である配列要素に一致します。

grep$_の使用は、perldocに記載されています。 &の意味もperldocです。

2
grep{ $_ & 1} 

これはgrepのは最後として1(LSB)ビットを持つすべての要素にマッチすることを意味し、あなたの配列の各要素の上に行くと1 で、ビット単位の試合を行います。 のみ奇数のLSBこれが唯一の奇数が返され

& is the bitwise AND 
0

$_を取得することはgrepの機能により設定された変数です。 perl関数のほとんどは、特に指定がない場合は$ _を操作します。 Grepは、@ arrayの要素ごとに定義された匿名サブタイプ({ $_ & 1 })を呼び出し、ビット単位で&を作成します。結果が真の値の場合、結果の配列に追加されます。

4

多くの人が指摘しているように、&はビット単位の演算子です。これは、比較される二つの数字はビットになって、比較されていることを意味する:

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

同様に、4 & 1戻り0である:grepの内部真と評価例えば

3 & 1戻り1、偽:奇数をフィルタリングする別の方法がある、と述べた

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 
関連する問題