Wenn ich das folgende Array in Perl habe:
@x = qw(a b c);
und ich iteriere darüber mit foreach
, dann $_
verweise ich auf das aktuelle Element im Array:
foreach (@x) {
print;
}
wird drucken:
abc
Gibt es eine ähnliche Möglichkeit, den Index des aktuellen Elements abzurufen, ohne einen Zähler manuell zu aktualisieren? So etwas wie:
foreach (@x) {
print $index;
}
Wo $index
wird aktualisiert $_
, um die Ausgabe zu erhalten:
012
next unless defined $x[$i];
am Anfang der Schleife zu setzen. Dies scheint auch für alle riskanteren Lösungen zu gelten, die while / each und for / keys betreffen. Anscheinend sieht der Array-Iterator jeden sequentiellen Index, ob er existiert oder nicht.$x[$i] // next;
In Perl vor 5.10 kann man 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 denen, die mit my erstellt wurden ). Auf diese Weise können Sie die
$index
Variable in einem kleineren Bereich halten, dies kann jedoch zu Fehlern führen (wenn Sie die Schleife ein zweites Mal betreten, 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: Sie haben Einschränkungen , was Sie tun dürfen,
@a
während Sie darüber iteriereneach
.Es wird dir jetzt nicht helfen, aber in Perl 6 kannst du es 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 komprimiert die beiden Listen zusammen (dh er nimmt ein Element aus der ersten Liste, dann ein Element aus der zweiten, dann ein Element aus der ersten usw.). Die zweite Liste ist eine faule Liste, die (zumindest theoretisch) jede ganze Zahl von 0 bis unendlich enthält. Das-> $elem, $index
sagt, dass wir zwei Werte gleichzeitig aus dem Ergebnis der Zip nehmen. Der Rest sollte für Sie normal aussehen (es sei denn, Sie sind mit dersay
Funktion ab 5.10 noch nicht vertraut ).quelle
state
, ich denke, es wäre besser, wenn man ihn bedient{ my $index; ... }
.perldoc perlvar
scheint keine solche Variable vorzuschlagen.quelle
perldoc perlvar
, würden Sie wissen warum. Es sind nur die in aufgelisteten Variablenperldoc perlvar
vorhanden. Eine solche Variable existiert, wie ich bereits sagte, nicht.Nicht mit
foreach
.Wenn Sie die Elementkardinalität im Array definitiv benötigen, verwenden Sie einen 'for'-Iterator:
for ($i=0; $i<@x; ++$i) { print "Element at index $i is " , $x[$i] , "\n"; }
quelle
Dies kann mit einer
while
Schleife erfolgen (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
Perl-Version: 5.14.4
quelle
Nein, Sie müssen Ihren eigenen Zähler erstellen. Noch ein Beispiel:
my $index; foreach (@x) { print $index++; }
wenn für die Indizierung verwendet
my $index; foreach (@x) { print $x[$index]+$y[$index]; $index++; }
Und natürlich können Sie
local $index;
stattdessenmy $index;
und so und so verwenden.quelle
for
Schleifensyntax vonfor(my $index; $index <= $#x; $index++){}
.Ja. Ich habe so viele Bücher und andere Blogs überprüft ... Die Schlussfolgerung ist, dass es keine Systemvariable für den Schleifenzähler gibt. Wir müssen unseren eigenen Zähler machen. Korrigiere mich, wenn ich falsch liege.
quelle
for
(akaforeach
) mit der optionalen langen Syntax vonfor($i=0;$i<=$#array;$i++){}
.autobox::Core
bietet unter anderem eine praktischefor
Methode:use autobox::Core; ['a'..'z']->for( sub{ my ($index, $value) = @_; say "$index => $value"; });
Schauen Sie sich alternativ ein Iteratormodul 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:
perl5i
quelle
Oh ja, das kannst du! (irgendwie, aber du solltest nicht).
each(@array)
In einem skalaren Kontext erhalten Sie den aktuellen Index des Arrays.@a = (a..z); for (@a) { print each(@a) . "\t" . $_ . "\n"; }
Hier
each(@a)
ist in einem skalaren Kontext und gibt nur den Index zurück, nicht den Wert an diesem Index. Da wir uns in einerfor
Schleife befinden, haben wir bereits den Wert in $ _. Der gleiche Mechanismus wird häufig in einer while-each-Schleife verwendet. Gleiches Problem.Das Problem tritt auf, wenn Sie es
for(@a)
erneut tun . Der Index ist nicht wie erwartet auf 0 zurück. esundef
folgt 0,1,2 ... eine Zählung. Der Perldoc voneach()
sagt, um dieses Problem zu vermeiden. Verwenden Sie einefor
Schleife, um den Index zu verfolgen.jeder
Grundsätzlich:
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++; }
quelle
each(@a)
innerhalb der Schleife erneut verwendenprint each(@a)."=< $_ >=".each(@a);
.Beachten Sie bitte:
print "Element at index $_ is $x[$_]\n" for keys @x;
quelle
keys @x
sich das so verhält, wie du denkst. Ich würde erwarten, dass es jedes gerade indizierte Element zurückgibt.for keys @x
befindet sich in einem Listenkontext, gibt den aktuellen Index zurück, und um den Wert zu erhalten, müssen Sie darauf verweisen$x[$_]
--- Eine besser lesbare Möglichkeit, genau dasselbe zu schreiben, istfor my $idx (keys @x){print "Element at index $idx is $x[$idx]\n";}
Nun, es gibt diesen Weg:
use List::Rubyish; $list = List::Rubyish->new( [ qw<a b c> ] ); $list->each_index( sub { say "\$_=$_" } );
Siehe List :: Rubyish .
quelle
In den meisten Fällen sollten Sie den Index nicht kennen müssen. Du kannst das:
my @arr = (1, 2, 3); foreach (@arr) { $_++; } print join(", ", @arr);
In diesem Fall wäre die Ausgabe 2, 3, 4, da foreach einen Alias für das eigentliche Element festlegt, nicht nur für eine Kopie.
quelle
Ich habe versucht wie ....
@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 the 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;
quelle