Wenn ich das folgende Array in Perl habe:
@x = qw(a b c);
und ich iteriere mit foreach
darüber, dann verweist $_
auf das aktuelle element im Array:
foreach (@x) {
print;
}
wird drucken:
abc
Gibt es einen ähnlichen Weg, um den Index des aktuellen Elements abzurufen, ohne einen Zähler manuell zu aktualisieren? Etwas wie:
foreach (@x) {
print $index;
}
wobei $index
wie $_
aktualisiert wird, um die Ausgabe zu erhalten:
012
Wie Codehead bereits sagt, müssten Sie statt der Elemente die Array-Indizes durchlaufen. Ich bevorzuge diese Variante dem C-Stil für die Schleife:
for my $i (0 .. $#x) {
print "$i: $x[$i]\n";
}
In Perl vor 5.10 können Sie sagen
#!/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";
}
In Perl 5.10 verwenden Sie state , um eine Variable zu deklarieren, die niemals neu initialisiert wird (im Gegensatz zu solchen, die mit my erstellt werden). Auf diese Weise können Sie die Variable $index
in einem kleineren Bereich halten, jedoch zu Fehlern führen (wenn Sie die Schleife ein zweites Mal eingeben, hat sie immer noch den letzten Wert):
#!/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";
}
In Perl 5.12 kann man sagen
#!/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";
}
Aber seien Sie gewarnt: Es gibt einschränkungen , was Sie mit @a
machen dürfen, während Sie mit each
iterieren.
Es wird dir jetzt nicht helfen, aber in Perl 6 kannst du sagen
#!/usr/bin/Perl6
my @a = <a b c d e>;
for @a Z 0 .. Inf -> $elem, $index {
say "at index $index, I saw $elem"
}
Der Z
-Operator zippt die beiden Listen zusammen (d. H. Er nimmt ein Element aus der ersten Liste, dann ein Element aus der zweiten Liste, dann ein Element aus der ersten Liste usw.). Die zweite Liste ist eine Lazy - Liste, die jede ganze Zahl von 0 bis unendlich (zumindest theoretisch) enthält. Der -> $elem, $index
sagt aus, dass wir jeweils zwei Werte aus dem Ergebnis des Zip-Werts nehmen. Der Rest sollte für Sie normal aussehen (es sei denn, Sie kennen die Funktion say
aus 5.10 noch nicht).
perldoc perlvar
scheint keine solche Variable vorzuschlagen.
Nicht bei foreach . Wenn Sie definitiv das Element cardinality im Array benötigen, verwenden Sie einen "for" -Iterator.
for($i=0;$i<@x;++$i) {
print "Element at index $i is ",$x[$i],"\n";
}
Perl-Version 5.14.4
Kann mit while
loop gemacht werden (foreach
unterstützt dies nicht)
my @arr = (1111, 2222, 3333);
while (my ($index, $element) = each(@arr))
{
# You may need to "use feature 'say';"
say "Index: $index, Element: $element";
}
Ausgabe:
Index: 0, Element: 1111
Index: 1, Element: 2222
Index: 2, Element: 3333
Ja. Ich habe so viele Bücher und andere Blogs geprüft ... Fazit: Es gibt keine Systemvariable für den Schleifenzähler. Wir müssen unseren eigenen Zähler machen. korrigiere mich, wenn ich falsch liege.
Nein, Sie müssen Ihren eigenen Zähler erstellen. Noch ein weiteres Beispiel:
my $index;
foreach (@x) {
print $index++;
}
bei der Indizierung verwendet
my $index;
foreach (@x) {
print $x[$index]+$y[$index];
$index++;
}
Und natürlich können Sie local $index;
anstelle von my $index;
und so und so verwenden.
EDIT: Entsprechend dem Kommentar des ersten Jahres aktualisiert.
autobox::Core
bietet neben vielen anderen Dingen eine praktische for
-Methode:
use autobox::Core;
['a'..'z']->for( sub{
my ($index, $value) = @_;
say "$index => $value";
});
Alternativ sehen Sie sich ein Iterator-Modul an, zum Beispiel: Array::Iterator
use Array::Iterator;
my $iter = Array::Iterator->new( ['a'..'z'] );
while ($iter->hasNext) {
$iter->getNext;
say $iter->currentIndex . ' => ' . $iter->current;
}
Siehe auch:
/ I3az /
Nun gibt es diesen Weg:
use List::Rubyish;
$list = List::Rubyish->new( [ qw<a b c> ] );
$list->each_index( sub { say "\$_=$_" } );
siehe Liste :: Rubyish
Oh ja das kannst du! (irgendwie, aber du solltest nicht). each(@array)
im skalaren Kontext gibt Ihnen den aktuellen Index des Arrays.
@a = (a..z);
for (@a){
print each(@a) . "\t" . $_ . "\n";
}
Hier befindet sich each(@a)
in einem skalaren Kontext und gibt nur den Index zurück, nicht den Wert an diesem Index. Da wir uns in einer for-Schleife befinden, haben wir den Wert bereits in $ _. Der gleiche Mechanismus wird häufig in einer While-Each-Schleife verwendet. Gleiches Problem.
Das Problem tritt auf, wenn Sie for(@a)
erneut ausführen, der Index nicht wie erwartet auf 0 zurückgesetzt ist, sondern undef
gefolgt von 0,1,2 ... einem Countdown. Die Perldoc von each()
sagt, um dieses Problem zu vermeiden, verwenden Sie eine for
-Schleife, um den Index zu verfolgen. https://perldoc.Perl.org/functions/each.html
Grundsätzlich gilt:
for(my $i=0; $i<=$#a; $i++){
print "The Element at $i is $a[$i]\n";
}
Ich bin ein Fan der alternativen Methode:
my $index=0;
for (@a){
print "The Element at $index is $a[$index]\n";
$index++;
}
Ich habe es gerne versucht ....
@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.
zusamenfassend..
@array = qw /a b c d/;
my $count;
for (@array) { print "\n",$count++," $_"; }
undef $count;
Beachten Sie bitte:
print "Element at index $_ is $x[$_]\n" for keys @x;
Sie sollten den Index in den meisten Fällen nicht kennen müssen, Sie können dies tun
my @arr = (1, 2, 3);
foreach (@arr) {
$_++;
}
print join(", ", @arr);
In diesem Fall wäre die Ausgabe 2, 3, 4 , da foreach einen Alias auf das eigentliche Element setzt, nicht nur eine Kopie.