2013-04-17 11 views
9

Sono perl principiante, sto leggendo sulla funzione grep per filtrare un elenco. Mi sono imbattuto nel seguente programma.

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

la dichiarazione my @subArray = grep { $_ & 1 } @array; rendimenti dispari-numeri in @array. Non ho capito come funziona l'espressione ($_ & 1). Ho cercato su Google ma non ho trovato link utili.

  • È che tipo di operatore speciale?

  • Esistono altre varianti di quello EXPR?

Grazie in anticipo.

+0

FYI: questo è un hack molto ordinato ** che non dovrebbe mai essere utilizzato nel codice di produzione ** meno che l'operazione di trovare elementi solo dispari è valutato per essere un collo di bottiglia in un implementazione più leggibile. – DVK

+0

@DVK Hm, come per il mio interesse: questo suggerimento è usato? '$ _ || = $ val' – gaussblurinc

+0

@loldop - L'operatore' || = 'è perfettamente idiologico Perl, non un hack. Tuttavia, l'uso di '$ _' anziché utilizzare una variabile variata in modo auto-documentato è molto spesso un segno di codice scritto male se non utilizzato in un blocco' map'/'grep' molto breve. – DVK

risposta

10

$_ è la variabile che tiene il valore attualmente testato, & è il binario operatore, e 1 è solo il numero uno. Questa espressione combina tutti i bit di $_ e di 1 l'uno con l'altro mediante AND logico. Quindi restituisce 1 se il valore è dispari e 0 se il valore è pari.

Ad esempio, assumiamo $ _ è 123 quindi la rappresentazione binaria sarebbe 1111011. Il numero decimale 1 sarebbe 00000001, così che unisce tutti i bit da e si ottiene

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

altro esempio 200 & 100

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

Nel secondo esempio ('200 e 100'), la risposta è' 64' o il mio modo di conversione è sbagliato? –

+0

Hai ragione, che deve essere 64 ovviamente. Il 128 è stato un errore da parte mia. – tauli

1

$_ è l'espressione corrente. In questo caso ogni elemento dell'array.

& è l'operatore AND binario.

Quindi, in breve, lo grep corrisponderà a qualsiasi elemento di matrice che è un numero dispari.

L'uso di $_ con grep è documentato nello perldoc. Il significato di & si trova anche nello perldoc.

2
grep{ $_ & 1} 

andrà oltre ogni elemento dell'array e fare una partita di bit per bit con 1 Ciò significa che grep corrisponderà ogni elemento che possiede una come ultima (LSB) bit 1. Da solo numeri dispari hanno un 1 come lsb questa torneranno solo numeri dispari

& is the bitwise AND 
0

$_ è una variabile impostata dalla funzione grep. La maggior parte delle funzioni di perl manipola $ _ se non specificato diversamente. Grep chiama il sub anonimo definito (che è { $_ & 1 }) per ogni elemento di @array e esegue un bit per bit &. Se il risultato è un valore vero, viene aggiunto all'array risultante.

4

Come molti hanno sottolineato, & è l'operatore bitwise e.Ciò significa che i due numeri che vengono comparati sono trasformati in bit e confrontate:

Ad esempio, 3 & 1 rendimenti 1, che restituisce True all'interno grep:

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

Analogamente, 4 & 1 rendimenti 0, che è falso:

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

detto questo, Un modo alternativo per filtrare i numeri dispari è al mod il numero con 2:

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