Если у меня есть следующий массив в Perl:
@x = qw(a b c);
и я перебираю его с помощью foreach
, тогда $_
будет ссылаться на текущий элемент в массиве:
foreach (@x) {
print;
}
напечатает:
abc
Есть ли аналогичный способ получить индекс текущего элемента, без ручного обновления счетчика? Что-то вроде:
foreach (@x) {
print $index;
}
где $index
обновляется как $_
, чтобы получить результат:
012
Как и codehead, вам придется перебирать индексы массива вместо его элементов. Я предпочитаю этот вариант для цикла цикла C:
for my $i (0 .. $#x) {
print "$i: $x[$i]\n";
}
В Perl до 5.10 вы можете сказать
#!/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";
}
В Perl 5.10 вы используете state, чтобы объявить переменную, которая никогда не получает повторной инициализации (в отличие от тех, которые создаются с помощью my). Это позволяет сохранить переменную $index
в меньшей области, но может привести к ошибкам (если вы введете цикл во второй раз, все равно будет иметь последнее значение):
#!/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";
}
В Perl 5.12 вы можете сказать
#!/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";
}
Но будьте осторожны: у вас есть ограничения на то, что вам разрешено делать с @a
, итерации по нему с помощью each
.
Теперь вам это не поможет, но в Perl 6 вы сможете сказать
#!/usr/bin/perl6
my @a = <a b c d e>;
for @a Z 0 .. Inf -> $elem, $index {
say "at index $index, I saw $elem"
}
Оператор Z
связывает два списка вместе (т.е. он берет один элемент из первого списка, затем один элемент из второго, затем один элемент из первого и т.д.). Второй список - это lazy список, содержащий все целые числа от 0 до бесконечности (по крайней мере теоретически). -> $elem, $index
говорит, что мы берем два значения за раз от результата zip. Остальное должно выглядеть нормально для вас (если вы еще не знакомы с функцией say
от 5.10).
state
, я думаю, что он будет лучше обслуживаться { my $index; ... }
perldoc perlvar
, похоже, не предлагает такую переменную.
Не с foreach. Если вам определенно нужна мощь элемента в массиве, используйте итератор 'for'.
for($i=0;$i<@x;++$i) {
print "Element at index $i is ",$x[$i],"\n";
}
Perl версия 5.14.4
Может быть сделано с помощью цикла while
(foreach
не поддерживает это)
my @arr = (1111, 2222, 3333);
while (my ($index, $element) = each(@arr))
{
# You may need to "use feature 'say';"
say "Index: $index, Element: $element";
}
Вывод:
Index: 0, Element: 1111
Index: 1, Element: 2222
Index: 2, Element: 3333
Да. Я проверил так много книг и других блогов... вывод заключается в том, что для счетчика циклов нет системной переменной. мы должны сделать свой счетчик. исправьте меня, если я ошибаюсь.
Нет, вы должны сделать свой счетчик. Еще один пример:
my $index;
foreach (@x) {
print $index++;
}
при индексировании
my $index;
foreach (@x) {
print $x[$index]+$y[$index];
$index++;
}
И, конечно, вы можете использовать local $index;
вместо my $index;
и так далее.
EDIT: обновлено в соответствии с первым ysth комментарием.
autobox::Core
предоставляет еще много удобного метода for
:
use autobox::Core;
['a'..'z']->for( sub{
my ($index, $value) = @_;
say "$index => $value";
});
Альтернативно посмотрите на модуль итератора, например: Array::Iterator
use Array::Iterator;
my $iter = Array::Iterator->new( ['a'..'z'] );
while ($iter->hasNext) {
$iter->getNext;
say $iter->currentIndex . ' => ' . $iter->current;
}
Также смотрите:
/I3az/
Я пробовал как....
@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.
короче..
@array = qw /a b c d/;
my $count;
for (@array) { print "\n",$count++," $_"; }
undef $count;
Вам не нужно знать индекс в большинстве случаев, вы можете это сделать
my @arr = (1, 2, 3);
foreach (@arr) {
$_++;
}
print join(", ", @arr);
В этом случае вывод будет 2, 3, 4, поскольку foreach устанавливает псевдоним для фактического элемента, а не только для копии.
Ну так:
use List::Rubyish;
$list = List::Rubyish->new( [ qw<a b c> ] );
$list->each_index( sub { say "\$_=$_" } );
см. List::Rubyish