2013-04-17 5 views
9

Ich bin perl Anfänger, ich lese auf grep Funktion, um eine Liste zu filtern. Ich stieß auf folgendes Programm.

#!/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; 

die Aussage my @subArray = grep { $_ & 1 } @array; kehrt ungerade Zahlen in @array. Ich habe nicht verstanden, wie der Ausdruck ($_ & 1) funktioniert. Ich habe in Google gesucht, aber keine nützlichen Links gefunden.

  • Ist das eine Art spezieller Operator?

  • Gibt es weitere Varianten davon EXPR?

Vielen Dank im Voraus.

+0

FYI besser lesbare Implementierung. – DVK

+0

@DVK Hm, Was mein Interesse betrifft: Wird dieser Tipp verwendet? '$ _ || = $ val' – gaussblurinc

+0

@loldop -' || = 'Operator ist perfekt idiomatische Perl, kein Hack. Allerdings ist die Verwendung von '$ _' im Gegensatz zur Verwendung einer selbst-dokumentierten Variablen sehr häufig ein Zeichen für schlecht geschriebenen Code, es sei denn, es wird in einem sehr kurzen' map'/'grep'-Block verwendet. – DVK

Antwort

10

$_ zurückkehren wird, ist die Variable, die den aktuell getesteten Wert hält, & die binäre ist AND-Operator, und 1 ist nur die Nummer eins. Dieser Ausdruck kombiniert alle Bits von $_ und 1 miteinander durch logisches UND. So gibt es 1 zurück, wenn der Wert ungerade ist, und 0, wenn der Wert gerade ist.

Als Beispiel nehmen wir an, $ _ ist 123 dann wäre es binäre Darstellung würde 1111011 sein. Die Dezimalzahl 1 würde 00000001 sein, so dass alle Bits Kombination von AND Sie

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

Ein anderes Beispiel 200 & 100

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

Im zweiten Beispiel ('200 & 100'), ist die Antwort' 64' oder meine Art der Konvertierung ist falsch? –

+0

Sie haben Recht, das muss natürlich 64 sein. Die 128 war ein Fehler meinerseits. – tauli

1

$_ ist der aktuelle Ausdruck. In diesem Fall jedes Array-Element.

& ist der binäre AND-Operator.

Kurz gesagt, passt die grep jedes Array-Element, das eine ungerade Zahl ist.

Die Verwendung von $_ mit grep ist in der perldoc dokumentiert. Die Bedeutung von & ist auch in der perldoc.

2
grep{ $_ & 1} 

Werden jedes Element Ihres Arrays gehen und tun, um eine bitweise Übereinstimmung mit 1 Das bedeutet, dass grep jedes Element übereinstimmen, die einen 1 zuletzt (lsb) Bit hat. Da nur ungerade Zahlen haben eine 1 als lsb dies nur ungerade Zahlen

& is the bitwise AND 
0

$_ ist eine Variable, die grep Funktion gesetzt bekommen. Die meisten Perl-Funktionen manipulieren $ _, wenn nicht anders angegeben. Grep ruft die definierte anonyme Sub-Adresse ({ $_ & 1 }) für jedes Element von @array auf und erstellt eine bitweise &. Wenn das Ergebnis ein wahrer Wert ist, wird es dem resultierenden Array hinzugefügt.

4

Wie viele darauf hingewiesen haben, ist & der Bitwise-Operator.Dies bedeutet, daß die zwei Zahlen, die verglichen werden, werden in die Bits eingeschaltet und miteinander verglichen:

Zum Beispiel 3 & 1 kehrt 1, die im Inneren des grep true ergibt:

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

Ähnlich 4 & 1 kehrt 0, das ist false:

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

das heißt, eine alternative Art und Weise zu filtern ungeraden Zahlen ist zu mod die Zahl mit 2: dies ist ein sehr ordentlich Hack **, dass nie in Produktionscode verwendet werden soll ** es sei denn, der Betrieb nur ungeradee Elemente zu finden, ist gebenchmarkt eine Performance-Engpass in einem sein:

my @odd = grep { $_ % 2 } 1 .. 7; # 1, 3, 5, 7 
Verwandte Themen