2011-07-15 8 views
5

¿Hay una manera rápida y fácil de grep a través de una matriz para encontrar los elementos que satisfacen algunas pruebas y eliminarlos de la matriz original?¿Cómo puedo grep a través de una matriz, mientras filtrado las coincidencias?

Por ejemplo, me gustaría

@a = (1, 7, 6, 3, 8, 4); 
@b = grep_filter { $_ > 5 } @a; 

# now @b = (7, 6, 8) 
# and @a = (1, 3, 4) 

En otras palabras, quiero dividir una matriz en dos matrices: las que coinciden y los que no se ajustan a una determinada condición.

+0

por qué? Es trivial y fácil de leer crear 2 arreglos de @a ('foreach (@a) {if ($ _> 5) {push @b, $ _;} else {push @c, $ _;}} ') ¿por qué necesita hacer esto" parcialmente en su lugar "? – mirod

+0

porque soy flojo. –

Respuesta

9

Conozca sus bibliotecas, mang.

use List::MoreUtils qw(part); 
part { $_>5 } (1, 7, 6, 3, 8, 4) 

vuelve

(
    [1, 3, 4], 
    [7, 6, 8], 
) 
+0

Agradable, más o menos lo que estaba buscando. –

-1

¿Esto es lo que quieres?

@a = (1, 7, 6, 3, 8, 4); 
@b = grep_filter { $_ > 5 } @a; 
@a = grep_filter { $_ < 5 } @a; 

hacer otro grep con su condición negated.

+1

'<' no es la estricta negación de '>'. – Alnitak

+0

@Alnitak - tienes razón, no lo mencioné, pero puse '<' y no '<=' para que el código funcione como se esperaba –

+0

@Tudor: por qué un código de error lógico funcionaría como código esperado, en lugar de la correcta <=? – pavel

8
my @a = (1, 7, 6, 3, 8, 4); 
my (@b, @c);  

push @{ $_ > 5 ? \@b : \@c }, $_ for @a; 
+0

+1 porque es una buena solución que no requiere ninguna biblioteca externa. –

3

uso de las bibliotecas es bueno, pero está completo, aquí es la función como se especifica en la pregunta:

sub grep_filter (&\@) { 
    my ($code, $src) = @_; 
    my ($i, @ret) = 0; 
    local *_; 
    while ($i < @$src) { 
     *_ = \$$src[$i]; 
     &$code 
      ? push @ret, splice @$src, $i, 1 
      : $i++ 
    } 
    @ret 
} 

my @a = (1, 7, 6, 3, 8, 4); 
my @b = grep_filter {$_ > 5} @a; 

say "@a"; # 1 3 4 
say "@b"; # 7 6 8 
Cuestiones relacionadas