J'essaie de trouver un moyen de vérifier l'existence d'une valeur dans un tableau sans parcourir le tableau.
Je lis un fichier pour un paramètre. J'ai une longue liste de paramètres que je ne veux pas traiter. J'ai placé ces paramètres indésirables dans un tableau @badparams
.
Je veux lire un nouveau paramètre et s'il n'existe pas @badparams
, le traiter. S'il existe @badparams
, passez à la lecture suivante.
Réponses:
Transformez simplement le tableau en hachage:
Vous pouvez également ajouter d'autres paramètres (uniques) à la liste:
Et plus tard, récupérez une liste de paramètres (uniques):
la source
1
.Meilleur usage général - Tableaux particulièrement courts (1000 éléments ou moins) et codeurs qui ne savent pas quelles optimisations répondent le mieux à leurs besoins.
Il a été mentionné que grep passe par toutes les valeurs même si la première valeur du tableau correspond. C'est vrai, cependant grep est toujours extrêmement rapide dans la plupart des cas . Si vous parlez de tableaux courts (moins de 1000 éléments), la plupart des algorithmes seront de toute façon assez rapides. Si vous parlez de tableaux très longs (1 000 000 éléments), grep est suffisamment rapide, que l'élément soit le premier, le milieu ou le dernier du tableau.
Cas d'optimisation pour les baies plus longues:
Si votre tableau est trié , utilisez une "recherche binaire".
Si le même tableau est recherché plusieurs fois à plusieurs reprises, copiez-le d'abord dans un hachage, puis vérifiez le hachage. Si la mémoire est un problème, déplacez chaque élément du tableau dans le hachage. Plus efficace en mémoire mais détruit la baie d'origine.
Si les mêmes valeurs sont recherchées à plusieurs reprises dans le tableau, créez paresseusement un cache. (comme chaque élément est recherché, vérifiez d'abord si le résultat de la recherche a été stocké dans un hachage persistant. si le résultat de la recherche n'est pas trouvé dans le hachage, puis recherchez dans le tableau et placez le résultat dans le hachage persistant de sorte que la prochaine fois nous le trouver dans le hachage et sauter la recherche).
Remarque: ces optimisations ne seront plus rapides que pour les tableaux longs. N'optimisez pas trop.
la source
Vous pouvez utiliser la fonction smartmatch dans Perl 5.10 comme suit:
Pour la recherche de valeur littérale, faire ci-dessous fera l'affaire.
Pour la recherche scalaire, faire ci-dessous fonctionnera comme ci-dessus.
Pour le tableau en ligne faisant ci-dessous, fonctionnera comme ci-dessus.
Dans Perl 5.18, smartmatch est marqué comme expérimental, vous devez donc désactiver les avertissements en activant le pragma expérimental en ajoutant ci-dessous à votre script / module:
Alternativement, si vous voulez éviter l'utilisation de smartmatch - alors comme Aaron l'a dit, utilisez:
la source
use experimental 'smartmatch'
est recommandé. Comme j'ai le contrôle de ma version Perl (système interne), j'utilise lano warnings 'experimental::smartmatch';
déclaration.Ce billet de blog discute des meilleures réponses à cette question.
En résumé, si vous pouvez installer des modules CPAN, les solutions les plus lisibles sont:
ou
Cependant, un idiome plus courant est:
Mais n'utilisez pas la
first()
fonction! Il n'exprime pas du tout l'intention de votre code. N'utilisez pas l'~~
opérateur "Smart match": il est cassé. Et n'utilisezgrep()
ni la solution avec un hachage: ils parcourent toute la liste.any()
s'arrêtera dès qu'il trouvera votre valeur.Consultez le billet de blog pour plus de détails.
la source
use List::Util qw(any);
.List::Util
est dans les modules Core .Méthode 1: grep (peut faire attention alors que la valeur devrait être une expression régulière).
Essayez d'éviter d'utiliser
grep
, si vous regardez les ressources.Méthode 2: recherche linéaire
Méthode 3: utilisez un hachage
Méthode 4: smartmatch
(ajouté en Perl 5.10, marqué est expérimental en Perl 5.18).
Méthode 5: utilisez le module
List::MoreUtils
la source
Le benchmark de @ eakssjo est cassé - mesure la création de hachages en boucle vs la création de regex en boucle. Version fixe (plus j'ai ajouté
List::Util::first
etList::MoreUtils::any
):Et résultat (c'est pour 100_000 itérations, dix fois plus que dans la réponse de @ eakssjo):
la source
Même si elle est pratique à utiliser, il semble que la solution de conversion en hachage coûte beaucoup de performances, ce qui était un problème pour moi.
Sortie du test de référence:
la source
List::Util::first
est plus rapide car elle cesse d'itérer lorsqu'elle trouve une correspondance.grep
est beaucoup plus lent que la création de hachage et la recherche, car l'ancien est O (n) et le dernier O (1). Il suffit de faire la création de hachage une seule fois (en dehors de la boucle) et de pré-calculer l'expression régulière pour mesurer les méthodes uniquement ( voir ma réponse ).@files est un tableau existant
/^2[\d diplomate .\\d diplomatiqueA-za-z
la source
Vous voulez certainement un hachage ici. Placez les mauvais paramètres comme clés dans le hachage, puis décidez si un paramètre particulier existe dans le hachage.
Si vous êtes vraiment intéressé à le faire avec un tableau, regardez
List::Util
ouList::MoreUtils
la source
Vous pouvez procéder de deux manières. Vous pouvez utiliser le jeter les valeurs dans un hachage pour une table de recherche, comme suggéré par les autres articles. (Je vais ajouter juste un autre idiome.)
Mais s'il s'agit principalement de données de mots et pas trop de méta, vous pouvez les vider dans une alternance d'expressions régulières:
Cette solution devrait être réglée pour les types de «mauvaises valeurs» que vous recherchez. Et encore une fois, cela pourrait être totalement inapproprié pour certains types de cordes, donc avertissez emptor .
la source
@bad_param_lookup{@bad_params} = ()
, mais vous devrez utiliserexists
pour tester l'adhésion.Vous pouvez vérifier la cohérence des espaces de début numériques
la source