2010-11-22 10 views
4

J'ai une exigence où j'ai besoin d'exécuter une instruction à l'intérieur de la boucle pour la première occurrence d'une variable.Opérateur flip flop en perl

Par exemple: Compte tenu de ma gamme @rand_numbers = qw(1 2 1 2 3 1 3 2);
Je sais qu'il n'y a que 3 valeurs présentes dans le tableau (dans ce cas 1,2 et 3)
Je veux imprimer quelque chose (ou faire quelque chose) sur la première rencontre de chaque valeur (seulement dans la première rencontre et ne jamais la répéter pour la rencontre consécutive de la valeur correspondante).

suivante est une approche

my @rand_numbers = qw(1 2 1 2 3 1 3 2); 
my $came_across_1=0, $came_across_2=0, $came_across_3=0; 

for my $x(@rand_numbers) { 
    print "First 1\n" and $came_across_1=1 if($x==1 and $came_across_1==0); 
    print "First 2\n" and $came_across_2=1 if($x==2 and $came_across_2==0); 
    print "First 3\n" and $came_across_3=1 if($x==3 and $came_across_3==0); 
    print "Common op for -- $x \n"; 
} 

est-il un moyen d'obtenir le résultat ci-dessus avec aucune variable comme $came_across_x? [c'est à dire. ? Avec l'aide de l'opérateur flip-flop]

Merci, Ranjith

Répondre

11

Cela peut ne pas fonctionner pour votre situation de la vie réelle, mais il fonctionne pour votre échantillon, et peut vous donner une idée:

Il suffit d'utiliser un hachage comme le suggère @Chris.
my %seen; 
for my $x (@rand_numbers) { 
    print "First $x\n" unless $seen{$x}++; 
    print "Common op for -- $x\n" 
} 
+1

En supposant ce que vous voulez faire est la même pour chaque élément différent que vous rencontrez , vous pouvez facilement le factoriser dans un sous-programme et écrire 'do_for_first ($ x) à moins que $ seen {$ x} ++; do_for_all ($ x); ' –

+0

Salut Chris, mon motif principal n'était pas d'utiliser une variable temporaire [comme dans ce cas vous avez utilisé le hash '% seen']. Désolé si ma question était confuse. Cependant pour ce scénario ce que vous avez suggéré est l'approche optimale, mais pour comprendre les one-liners disponibles en perl, je me demandais si nous pouvions le faire seulement en utilisant l'opérateur flip-flop (ou un autre opérateur spécial/variable). – Ranjith

+0

@Ranjith Notez que l'utilisation d'une seule table de hachage est environ une fois et demie meilleure et plus flexible que vos variables '$ came_across_i'. –

3

Utilisation de l'opérateur bascule semble être ici pas pratique parce que vous aurez besoin de garder une trace de variables vu de toute façon:

my %seen; 
for (@rand_numbers) { 
    print "$_\n" if $_ == 1 && !$seen{$_}++ .. $_ == 1; 
    print "$_\n" if $_ == 2 && !$seen{$_}++ .. $_ == 2; 
    print "$_\n" if $_ == 3 && !$seen{$_}++ .. $_ == 3; 
}