Si j'ai le tableau suivant en Perl:
@x = qw(a b c);
et j'itère dessus avec foreach
, alors $_
fera référence à l'élément actuel du tableau:
foreach (@x) {
print;
}
imprimera:
abc
Existe-t-il un moyen similaire d’obtenir le index de l’élément en cours sans mettre à jour manuellement un compteur? Quelque chose comme:
foreach (@x) {
print $index;
}
où $index
est mis à jour comme $_
pour générer le résultat:
012
Comme dit Codehead, il vous faudrait parcourir les index du tableau plutôt que 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 strict;
use warnings;
my @a = qw/a b c d e/;
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";
}
Dans Perl 5.10, vous utilisez tat pour déclarer une variable qui ne sera jamais réinitialisée (contrairement à ceux créés avec my ). Cela vous permet de conserver la variable $index
dans une portée plus petite, mais peut entraîner des bugs (si vous entrez la boucle une seconde fois, elle aura toujours la dernière valeur):
#!/usr/bin/Perl
use 5.010;
use strict;
use warnings;
my @a = qw/a b c d e/;
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 strict
use warnings;
my @a = qw/a b c d e/;
while (my ($index, $elem) = each @a) {
say "At index $index I saw $elem";
}
Mais soyez averti: vous avez des restrictions à ce que vous êtes autorisé à faire avec @a
tout en itérant dessus avec each
.
Cela ne vous aidera pas maintenant, mais dans Perl 6, vous pourrez dire
#!/usr/bin/Perl6
my @a = <a b c d e>;
for @a Z 0 .. Inf -> $elem, $index {
say "at index $index, I saw $elem"
}
L’opérateur Z
compresse les deux listes ensemble (c’est-à-dire qu’il prend un élément de la première liste, puis un élément de la seconde, puis un élément de la première, etc.). La deuxième liste est une liste lazy qui contient tous les entiers de 0 à l’infini (au moins théoriquement). Le -> $elem, $index
indique que nous prenons deux valeurs à la fois du résultat du zip. Le reste devrait vous paraître normal (sauf si vous n'êtes pas encore familiarisé avec la fonction say
de 5.10).
perldoc perlvar
ne semble pas suggérer une telle variable.
Pas avec foreach . Si vous avez vraiment besoin de la cardinalité des éléments du tableau, utilisez un itérateur 'pour'.
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 le supporte pas)
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
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 comptoir. Corrige moi si je me trompe.
Non, vous devez faire votre propre comptoir. 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;
à la place de my $index;
et ainsi de suite.
EDIT: Mis à jour en fonction du commentaire du premier ysth.
autobox::Core
fournit, parmi beaucoup d'autres choses, une méthode pratique for
:
use autobox::Core;
['a'..'z']->for( sub{
my ($index, $value) = @_;
say "$index => $value";
});
Vous pouvez également consulter un module itérateur, 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:
/ I3az /
Eh bien, voici comment:
use List::Rubyish;
$list = List::Rubyish->new( [ qw<a b c> ] );
$list->each_index( sub { say "\$_=$_" } );
voir Liste :: Rubyish
Oh oui tu peux! (en quelque sorte, mais vous ne devriez pas). each(@array)
dans un contexte scalaire vous donne l'index actuel du tableau.
@a = (a..z);
for (@a){
print each(@a) . "\t" . $_ . "\n";
}
Ici, each(@a)
se trouve dans un contexte scalaire et renvoie uniquement l'index, pas la valeur de cet index. Puisque nous sommes dans une boucle for, nous avons déjà la valeur dans $ _. Le même mécanisme est souvent utilisé dans une boucle While-Each. Même problème.
Le problème vient si vous refaites for(@a)
, l'index n'est pas remis à 0 comme prévu, c'est undef
suivi de 0,1,2 ... un décompte. Le perldoc de each()
indique que pour éviter ce problème, utilisez une boucle for
pour suivre l'index. https://perldoc.Perl.org/functions/each.html
Fondamentalement:
for(my $i=0; $i<=$#a; $i++){
print "The Element at $i is $a[$i]\n";
}
Je suis fan de la méthode alternative:
my $index=0;
for (@a){
print "The Element at $index is $a[$index]\n";
$index++;
}
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++," $_" ; } # string 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 /a b c d/;
my $count;
for (@array) { print "\n",$count++," $_"; }
undef $count;
Veuillez considérer:
print "Element at index $_ is $x[$_]\n" for keys @x;
Vous ne devriez pas avoir besoin de connaître l'index dans la plupart des cas, vous pouvez le faire
my @arr = (1, 2, 3);
foreach (@arr) {
$_++;
}
print join(", ", @arr);
Dans ce cas, la sortie serait 2, 3, 4 car foreach définit un alias sur l'élément réel, pas seulement une copie.