2009-08-11 17 views

risposta

39

Le parentesi cambiano il contesto in cui l'grep viene valutata da un contesto scalare per elencare contesto. In contesto scalare, grep restituisce il numero di volte in cui l'espressione era vera. Nel contesto dell'elenco restituisce gli elementi per cui l'espressione era vera.

I seguenti punti salienti del contesto differenza fa:

my $x = grep {/foo/} @array; # the number of things that match /foo/ 
my ($x) = grep {/foo/} @array; # the first thing that matches /foo/ 
my @foo = grep {/foo/} @array; # all the things that match /foo/ 
my (@foo) = grep {/foo/} @array; # all the things that match /foo/ 
+0

'scalar @ array' è il numero di elementi in' @ array' –

1

grep restituisce una lista. Quando si inserisce il nome della variabile scalare tra parentesi, Perl considera l'intero valore-l come un elenco, quindi assegna il primo valore nell'elenco a tale variabile.

Se avete avuto altri scalari tra parentesi, che ci si ottenere i valori secondo, terzo, ecc da array di ritorno grep s' in loro:

my ($index, $foo, $bar) = grep { $array[$_] eq $search_for } 0..$#array; 
+3

grep restituisce un array. Ma solo nel contesto dell'array. – innaM

+0

E in contesto scalare restituisce il numero di volte in cui la corrispondenza è tornata vera, quindi in realtà non importa chi sta scalando la matrice. – Plutor

+1

@Plutor: i documenti dicono esplicitamente cosa significa 'grep', quindi non c'è giustificazione per la pubblicazione di una descrizione imprecisa. –

8

Le parentesi forniscono una list context per grep. grep restituirà effettivamente l'elenco di elementi per cui l'espressione era vera e non solo il numero di volte in cui l'espressione era vera.

+0

s/contesto array/contesto elenco/ –

+0

Molto meglio. Grazie. – innaM

+0

Prego. –

7

Penso che si sta cercando first_index da List::MoreUtils:

use List::MoreUtils qw(first_index); 

# ... 

my $index = first_index { $_ eq $search_for } @array; 
5

La funzione di grep comporta in modo diverso nel contesto di lista e un contesto scalare. Questo documentato in perldoc -f grep:

Valuta il BLOCCO o ESPR per ogni elemento della LISTA (localmente impostazione $ _ ogni elemento) e restituisce il valore della lista costituito da quegli elementi per i quali la valutazione dell'espressione su true. In contesto scalare, restituisce il numero di volte in cui l'espressione era vera.

È possibile duplicare da soli con il mal di nome wantarray funzione:

sub my_grep { 
    my $sub = shift; 
    my @return; 
    for my $item (@_) { 
     push @return if $sub->($item); 
    } 
    return @return if wantarray; 
    return scalar @return; 
} 
1

Inoltre, penso che usando grep solo per trovare la prima istanza è un po 'inefficiente dal momento che ha ancora a piedi attraverso ed esegui il callback su ogni elemento dell'array. Specialmente se il tuo array è lungo, potresti stare meglio scrivendo un loop o usando List :: MoreUtils come menzionato sopra.

Problemi correlati