2010-10-18 7 views
24

Aquí intento filtrar solo los elementos que no tienen una subcadena world y almacenar los resultados en la misma matriz. ¿Cuál es la forma correcta de hacer esto en Perl?¿Cómo puedo filtrar una matriz sin usar un bucle en Perl?

$ cat test.pl 
use strict; 
use warnings; 

my @arr = ('hello 1', 'hello 2', 'hello 3', 'world1', 'hello 4', 'world2'); 

print "@arr\n"; 
@arr =~ v/world/; 
print "@arr\n"; 

$ perl test.pl 
Applying pattern match (m//) to @array will act on scalar(@array) at 
test.pl line 7. 
Applying pattern match (m//) to @array will act on scalar(@array) at 
test.pl line 7. 
syntax error at test.pl line 7, near "/;" 
Execution of test.pl aborted due to compilation errors. 
$ 

Quiero pasar la matriz como argumento a una subrutina.

Yo sé una manera sería algo como esto

$ cat test.pl 
use strict; 
use warnings; 

my @arr = ('hello 1', 'hello 2', 'hello 3', 'world1', 'hello 4', 'world2'); 
my @arrf; 

print "@arr\n"; 

foreach(@arr) { 
    unless ($_ =~ /world/i) { 
     push (@arrf, $_); 
    } 
} 
print "@arrf\n"; 

$ perl test.pl 
hello 1 hello 2 hello 3 world1 hello 4 world2 
hello 1 hello 2 hello 3 hello 4 
$ 

quiero saber si hay una manera de hacerlo sin el bucle (usando algún tipo de filtrado simple).

Respuesta

31

Eso sería grep():

#!/usr/bin/perl 

use strict; 
use warnings; 

my @arr = ('hello 1', 'hello 2', 'hello 3', 'world1', 'hello 4', 'world2'); 
my @narr = (); 

print "@arr\n"; 
@narr = grep(!/world/, @arr); 
print "@narr\n"; 
8

Uso grep

@no_world_for_tomorrow = grep { !/world/ } @feathers; 

Para más detalles, perldoc -f grep.

4

Usted puede utilizar la función grep como:

@arrf = grep(!/world/, @arr); 

La expresión !/world/ se evalúa para cada elemento de la matriz @arr y una lista de elementos que la que se devuelve la expresión evaluada para ser verdad.

La expresión /world/ busca la palabra world y es cierto que está presente. Y la expresión !/world/ es verdadera si la cadena world está ausente.

11

Uso grep:

sub remove_worlds { grep !/world/, @_ } 

Por ejemplo:

@arrf = remove_worlds @arr; 

Usando grep es la forma más natural para su problema particular, pero para Completitud, también puede hacerlo con map:

sub remove_worlds { map /world/ ?() : $_, @_ } 

Es un poco klunky aquí, pero map le da un gancho en caso de que desee procesar los elementos filtrados antes de desecharlos.

+0

Es bueno tener los enlaces de referencia aquí. – Wolf

+0

Esa sintaxis de coincidencia negativa '!/Match /' fue crítica. Había estado considerando mapas y otras soluciones, pero todos parecían demasiado torpes para Perl. – davenpcj

Cuestiones relacionadas