Estoy tratando de encontrar una manera de verificar la existencia de un valor en una matriz sin iterar a través de la matriz.
Estoy leyendo un archivo para un parámetro. Tengo una larga lista de parámetros con los que no quiero tratar. Coloqué estos parámetros no deseados en una matriz @badparams
.
Quiero leer un nuevo parámetro y, si no existe @badparams
, procesarlo. Si existe @badparams
, vaya a la siguiente lectura.
perl
arrays
comparison
Mel
fuente
fuente
Respuestas:
Simplemente convierta la matriz en un hash:
También puede agregar más parámetros (únicos) a la lista:
Y luego obtenga una lista de parámetros (únicos):
fuente
1
nuevo.Mejor propósito general: especialmente matrices cortas (1000 elementos o menos) y codificadores que no están seguros de qué optimizaciones se adaptan mejor a sus necesidades.
Se ha mencionado que grep pasa por todos los valores, incluso si el primer valor de la matriz coincide. Esto es cierto, sin embargo, grep sigue siendo extremadamente rápido en la mayoría de los casos . Si está hablando de matrices cortas (menos de 1000 elementos), la mayoría de los algoritmos serán bastante rápidos de todos modos. Si está hablando de matrices muy largas (1,000,000 artículos) grep es aceptablemente rápido independientemente de si el artículo es el primero o el medio o el último en la matriz.
Casos de optimización para matrices más largas:
Si su matriz está ordenada , use una "búsqueda binaria".
Si la misma matriz se busca repetidamente muchas veces, cópiela primero en un hash y luego verifique el hash. Si le preocupa la memoria, mueva cada elemento de la matriz al hash. Más memoria eficiente pero destruye la matriz original.
Si se buscan repetidamente los mismos valores dentro de la matriz, construya un caché de forma perezosa. (a medida que se busca cada elemento, primero verifique si el resultado de la búsqueda se almacenó en un hash persistente. Si el resultado de la búsqueda no se encuentra en el hash, luego busque la matriz y coloque el resultado en el hash persistente para que la próxima vez búscalo en el hash y salta la búsqueda).
Nota: estas optimizaciones solo serán más rápidas cuando se trate de matrices largas. No lo optimices en exceso.
fuente
Puede usar la función smartmatch en Perl 5.10 de la siguiente manera:
Para la búsqueda de valor literal, hacer a continuación hará el truco.
Para la búsqueda escalar, hacer lo siguiente funcionará como lo hizo anteriormente.
Para la matriz en línea que se muestra a continuación, funcionará como se indica arriba.
En Perl 5.18, smartmatch se marca como experimental, por lo tanto, debe desactivar las advertencias activando pragma experimental agregando a continuación a su script / módulo:
Alternativamente, si desea evitar el uso de smartmatch, entonces, como Aaron dijo, use:
fuente
use experimental 'smartmatch'
se recomienda la configuración . Como tengo control de mi versión perl (sistema interno), uso lano warnings 'experimental::smartmatch';
declaración.Esta publicación de blog discute las mejores respuestas a esta pregunta.
Como breve resumen, si puede instalar módulos CPAN, las soluciones más legibles son:
o
Sin embargo, un idioma más común es:
¡Pero por favor no use la
first()
función! No expresa la intención de su código en absoluto. No utilice el~~
operador "Smart match": está roto. Y no usegrep()
ni la solución con un hash: iteran por toda la lista.any()
se detendrá tan pronto como encuentre su valor.Echa un vistazo a la publicación del blog para más detalles.
fuente
use List::Util qw(any);
.List::Util
está en los módulos principales .Método 1: grep (puede ser cuidadoso mientras se espera que el valor sea una expresión regular).
Intente evitar el uso
grep
, si observa los recursos.Método 2: búsqueda lineal
Método 3: usa un hash
Método 4: smartmatch
(agregado en Perl 5.10, marcado es experimental en Perl 5.18).
Método 5: usar el módulo
List::MoreUtils
fuente
El punto de referencia de @eakssjo está roto: mide la creación de hashes en bucle frente a la creación de expresiones regulares en bucle. Versión fija (además he agregado
List::Util::first
yList::MoreUtils::any
):Y resultado (es para 100_000 iteraciones, diez veces más que en la respuesta de @eakssjo):
fuente
Aunque es conveniente de usar, parece que la solución de conversión a hash cuesta bastante rendimiento, lo cual fue un problema para mí.
Salida de prueba de referencia:
fuente
List::Util::first
es más rápido ya que deja de iterar cuando encuentra una coincidencia.grep
es significativamente más lento que crear hash y realizar búsquedas, ya que el primero es O (n) y el último O (1). Simplemente haga la creación de hash solo una vez (fuera del ciclo) y precalcule la expresión regular para medir solo los métodos ( vea mi respuesta ).@files es una matriz existente
/^2[\dfont>.[\dfont>[A-za-zfont>?/ = valores a partir de 2 aquí puede poner cualquier expresión regular
fuente
Ciertamente quieres un hash aquí. Coloque los parámetros incorrectos como claves en el hash, luego decida si existe un parámetro particular en el hash.
Si está realmente interesado en hacerlo con una matriz, mire
List::Util
oList::MoreUtils
fuente
hay dos maneras de hacer esto. Puede usar arrojar los valores en un hash para una tabla de búsqueda, como lo sugieren las otras publicaciones. (Agregaré solo otro idioma).
Pero si se trata de datos de caracteres principalmente de palabras y no demasiados meta, puede volcarlos en una alternancia de expresiones regulares:
Esta solución tendría que ajustarse para los tipos de "valores incorrectos" que está buscando. Y de nuevo, puede ser totalmente inapropiado para ciertos tipos de cadenas, por lo que se debe advertir .
fuente
@bad_param_lookup{@bad_params} = ()
, pero necesitaría usarexists
para probar la membresía.Es posible que desee verificar la consistencia numérica de espacios iniciales
fuente