автоматически получите индекс цикла в цикле foreach в жемчуге

Если у меня есть следующий массив в Perl:

@x = qw(a b c);

и я выполняю итерации по нему с foreach, тогда $_ будет относиться к элементу тока в массиве:

foreach (@x) {
    print;
}

распечатает:

abc

Существует ли похожий способ получить индекс элемента тока, вручную не обновляя счетчик? Что-то, такое как:

foreach (@x) {
    print $index;
}

где $index обновляется как $_ привести к выводу:

012
75
задан Peter Mortensen 20 November 2019 в 12:53
поделиться

7 ответов

Как кодовый заголовок сказал , вам придется перебирать индексы массива вместо его элементов. Я предпочитаю этот вариант циклу для в стиле C:

for my $i (0 .. $#x) {
    print "$i: $x[$i]\n";
}
107
ответ дан 24 November 2019 в 11:29
поделиться

В 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 вы используете состояние для объявления переменной, которая никогда не будет повторно инициализирована (в отличие от переменных, созданных с помощью ] мой ). Это позволяет вам сохранить переменную $ 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 , при повторении с каждый .

Сейчас это вам не поможет, но в 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 объединяет два списка вместе (т.е. берет один элемент из первого списка, затем один элемент из второго, затем один элемент из первого и так далее). Второй список - это ленивый список, который содержит все целые числа от 0 до бесконечности (по крайней мере, теоретически). -> $ elem, $ index говорит, что мы берем сразу два значения из результата zip. Остальное должно выглядеть нормально для вас (если вы еще не знакомы с функцией , скажем, из 5.10).

43
ответ дан 24 November 2019 в 11:29
поделиться

Нет, вы должны создать свой собственный счетчик. Еще один пример:

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

при использовании для индексации

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

И, конечно же, вы можете использовать local $ index; вместо my $ index; и так далее.

5
ответ дан 24 November 2019 в 11:29
поделиться

perldoc perlvar , похоже, не предлагает такой переменной.

22
ответ дан 24 November 2019 в 11:29
поделиться

Не с foreach .

Если вам определенно нужна мощность элемента в массиве, используйте итератор «for»:

for ($i=0; $i<@x; ++$i) {
  print "Element at index $i is " , $x[$i] , "\n";
}
8
ответ дан 24 November 2019 в 11:29
поделиться

Вот такой способ:

use List::Rubyish;

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

См. List :: Rubyish .

1
ответ дан 24 November 2019 в 11:29
поделиться

В большинстве случаев вам не нужно знать индекс. Вы можете сделать это:

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

В этом случае вывод будет 2, 3, 4 , поскольку foreach устанавливает псевдоним для фактического элемента, а не только для его копии.

0
ответ дан 24 November 2019 в 11:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: