2011-10-26 17 views
16

Cada vez que ingreso algo, el código siempre me dice que existe. Pero sé que algunas de las entradas no existen. ¿Qué está mal?Grep para encontrar el elemento en la matriz Perl

#!/usr/bin/perl 

@array = <>; 
print "Enter the word you what to match\n"; 
chomp($match = <STDIN>); 

if (grep($match, @array)) { 
    print "found it\n"; 
} 

Respuesta

26

La primera arg que le dé a grep debe evaluarse como verdadera o falsa para indicar si hubo una coincidencia. Por lo que debe ser:

# note that grep returns a list, so $matched needs to be in brackets to get the 
# actual value, otherwise $matched will just contain the number of matches 
if (my ($matched) = grep $_ eq $match, @array) { 
    print "found it: $matched\n"; 
} 

Si tiene que coincidir en una gran cantidad de diferentes valores, sino que también valdría la pena para que usted considere poner los datos array en un hash, ya que los hashes le permiten hacer esto de manera eficiente y sin tener que iterar a través de la lista.

# convert array to a hash with the array elements as the hash keys and the values are simply 1 
my %hash = map {$_ => 1} @array; 

# check if the hash contains $match 
if (defined $hash{$match}) { 
    print "found it\n"; 
} 
23

Usted parece estar utilizando grep() como la utilidad Unix grep, lo cual es incorrecto.

Perl grep() en contexto escalar evalúa la expresión de cada elemento de una lista y devuelve el número de veces que la expresión fue verdadera. Entonces cuando $match contiene cualquier valor "verdadero", grep($match, @array) en contexto escalar siempre devolverá la cantidad de elementos en @array.

En su lugar, trate de usar el operador de coincidencia de patrones:

if (grep /$match/, @array) { 
    print "found it\n"; 
} 
+0

Creo que se podría volver a la palabra que esto sea más claro - aunque puedo ver lo que quiere decir en la re-lectura, en un principio suena como usted están diciendo que 'grep' en el contexto escalar devuelve la longitud de' @ array'. Como usted (con razón) pretendía, devuelve el número de veces que la expresión/bloque es verdadera. Si la expresión es * solo una variable * - es decir, no hay comparación real, solo la variable '$ match', entonces es verdadera para cada elemento si la variable en sí es verdadera (no vacía, distinta de cero, etc.) –

+1

@Sam : He intentado reformularlo, espero que ahora esté más claro. –

+1

@eugeney que me lee mucho mejor, ¡genial! –

1

Además de lo que Eugene y stevenl publicada, puede encontrarse con problemas con el uso tanto <> y <STDIN> en una secuencia de comandos: <> itera (= concatenar) todos los archivos dados como argumentos de línea de comando.

Sin embargo, si un usuario nunca se olvide de especificar un archivo en la línea de comandos, se leerá desde STDIN, y su código esperará para siempre en la entrada

2

Esto podría hacerse utilizando first función List::Util 's:

use List::Util qw/first/; 

my @array = qw/foo bar baz/; 
print first { $_ eq 'bar' } @array; 

Otras funciones de List::Util como max, min, sum también pueden ser útiles para usted

1

que podría suceder tha t si su matriz contiene la cadena "hola", y si está buscando "él", grep devuelve verdadero, aunque, "él" puede no ser un elemento de matriz.

Tal vez,

if (grep(/^$match$/, @array)) más aptos.

1

También puede comprobar el valor único en múltiples arreglos como,

if (grep /$match/, @array, @array_one, @array_two, @array_Three) 
{ 
    print "found it\n"; 
} 
+2

Bienvenido a Stackoverflow. ¿Te importaría ampliar tu respuesta un poco más para explicar cómo se resuelve el problema? – Daenarys

Cuestiones relacionadas