obtenir automatiquement l’index de boucle dans la boucle foreach dans perl

Si j’ai le tableau suivant en Perl:

@x = qw(abc); 

et je le répète avec foreach , alors $_ fera référence à l’ élément actuel du tableau:

 foreach (@x) { print; } 

imprimera:

 abc 

Existe-t-il une méthode similaire pour obtenir l’ index de l’élément actuel sans mettre à jour manuellement un compteur? Quelque chose comme:

 foreach (@x) { print $index; } 

$index est mis à jour comme $_ pour générer le résultat:

 012 

Comme l’a dit le codehead, il faudrait parcourir les index du tableau au lieu de ses éléments. Je préfère cette variante au style C pour la boucle:

 for my $i (0 .. $#x) { print "$i: $x[$i]\n"; } 

En Perl avant 5.10, vous pouvez dire

 #!/usr/bin/perl use ssortingct; use warnings; my @a = qw/abcde/; my $index; for my $elem (@a) { print "At index ", $index++, ", I saw $elem\n"; } #or for my $index (0 .. $#a) { print "At index $index I saw $a[$elem]\n"; } 

En Perl 5.10, vous utilisez state pour déclarer une variable qui ne sera jamais réinitialisée (contrairement à celles créées avec my ). Cela vous permet de garder la variable $index dans une plus petite scope, mais peut conduire à des bogues (si vous entrez la boucle une seconde fois, elle aura toujours la dernière valeur):

 #!/usr/bin/perl use 5.010; use ssortingct; use warnings; my @a = qw/abcde/; for my $elem (@a) { state $index; say "At index ", $index++, ", I saw $elem"; } 

En Perl 5.12, vous pouvez dire

 #!/usr/bin/perl use 5.012; #this enables ssortingct use warnings; my @a = qw/abcde/; while (my ($index, $elem) = each @a) { say "At index $index I saw $elem"; } 

Mais attention, il y a des ressortingctions à ce que vous êtes autorisé à faire avec @a en itérant avec each .

Cela ne vous aidera pas maintenant, mais en Perl 6 vous pourrez dire

 #!/usr/bin/perl6 my @a = ; for @a Z 0 .. Inf -> $elem, $index { say "at index $index, I saw $elem" } 

L’opérateur Z compresse les deux listes (c’est-à-dire qu’il prend un élément de la première liste, puis un élément du second, puis un élément du premier, etc.). La deuxième liste est une liste paresseuse qui contient tous les nombres entiers compris entre 0 et l’infini (du moins théoriquement). Le -> $elem, $index indique que nous prenons deux valeurs à la fois à partir du résultat du zip. Le rest devrait vous paraître normal (à moins que vous ne soyez pas familier avec la fonction say de 5.10).

perldoc perlvar ne semble pas suggérer une telle variable.

Pas avec foreach. Si vous avez absolument besoin de l’élément cardinality dans le tableau, utilisez un iterator ‘for’.

 for($i=0;$i<@x;++$i) { print "Element at index $i is ",$x[$i],"\n"; } 

Version Perl 5.14.4

Peut être fait avec la boucle while ( foreach ne supporte pas cela)

 my @arr = (1111, 2222, 3333); while (my ($index, $element) = each(@arr)) { # You may need to "use feature 'say';" say "Index: $index, Element: $element"; } 

Sortie:

 Index: 0, Element: 1111 Index: 1, Element: 2222 Index: 2, Element: 3333 

Non, vous devez créer votre propre compteur. Encore un autre exemple:

 my $index; foreach (@x) { print $index++; } 

lorsqu’il est utilisé pour l’indexation

 my $index; foreach (@x) { print $x[$index]+$y[$index]; $index++; } 

Et bien sûr, vous pouvez utiliser local $index; au lieu de cela, my $index; et ainsi de suite.

EDIT : Mis à jour selon le commentaire de la première fois.

Oui. J’ai vérifié tellement de livres et d’autres blogs … En conclusion, il n’y a pas de variable système pour le compteur de boucles. nous devons faire notre propre compteur. Corrige moi si je me trompe.

autobox::Core fournit entre autres choses une méthode pratique:

 use autobox::Core; ['a'..'z']->for( sub{ my ($index, $value) = @_; say "$index => $value"; }); 

Sinon, regardez un module iterator, par exemple: Array::Iterator

 use Array::Iterator; my $iter = Array::Iterator->new( ['a'..'z'] ); while ($iter->hasNext) { $iter->getNext; say $iter->currentIndex . ' => ' . $iter->current; } 

Regarde aussi:

  • chacun à sa façon (boîte automatique)
  • perl5i

/ I3az /

Eh bien, il y a cette façon:

 use List::Rubyish; $list = List::Rubyish->new( [ qw ] ); $list->each_index( sub { say "\$_=$_" } ); 

voir la liste :: Rubyish

Vous ne devriez pas avoir besoin de connaître l’index dans la plupart des circonstances, vous pouvez le faire

 my @arr = (1, 2, 3); foreach (@arr) { $_++; } print join(", ", @arr); 

Dans ce cas, le résultat serait 2, 3, 4 car foreach définit un alias pour l’élément réel, pas seulement une copie.

J’ai essayé comme ….

 @array = qw /tomato banana papaya potato/; # example array my $count; # local variable initial value will be 0 print "\nBefore For loop value of counter is $count"; # just printing value before entering in loop for (@array) { print "\n",$count++," $_" ; } # ssortingng and variable seperated by comma to # execute the value and print undef $count; # undefining so that later parts again it will # be reset to 0 print "\nAfter for loop value of counter is $count"; # checking the counter value after for loop. 

en bref..

 @array = qw /abcd/; my $count; for (@array) { print "\n",$count++," $_"; } undef $count; 

S’il vous plaît considérer:

 print "Element at index $_ is $x[$_]\n" for keys @x;