arrays - programas - sentencia perl
¿Cómo puedo filtrar una matriz sin usar un bucle en Perl? (4)
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";
Aquí estoy tratando de filtrar solo los elementos que no tienen un world
subcadenas y almacenar los resultados en la misma matriz. ¿Cuál es la forma correcta de hacer esto 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.
Sé que una de las formas 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 un simple filtrado).
Puede usar 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 a los que se les devuelve la expresión evaluada como verdadera.
La expresión /world/
busca la palabra world
y es verdad que está presente. Y la expresión !/world/
es verdadera si el world
cuerdas está ausente.
Usa grep
@no_world_for_tomorrow = grep { !/world/ } @feathers;
Para más detalles, perldoc -f grep
.
Use grep
:
sub remove_worlds { grep !/world/, @_ }
Por ejemplo:
@arrf = remove_worlds @arr;
Usar grep
es el ajuste más natural para su problema en particular, pero para completarlo, también puede hacerlo con un map
:
sub remove_worlds { map /world/ ? () : $_, @_ }
Aquí es un poco complicado, pero el map
te da un gancho en caso de que quieras procesar los elementos filtrados antes de descartarlos.