Как пройти по массиву в Perl

Задача. В коде Perl программы есть массив @arr (первые три буквы от слова "array"). В этом массиве есть какие-то значения. Нужно пройтись по всем элементам массива и выполнить какие-то действия с каждым элементом.

Пройтись по массиву с помощью foreach

Рекомендуемый способ для решения этой задачи — это использовать foreach. Вот пример программы:

▶ Run
#!/usr/bin/perl

my @arr = (1, 2, 3);

foreach my $el (@arr) {
    warn $el;
}

Тут все очень просто. Есть массив. Дальше мы создаем переменную $el (сокращение от слова element). Цикл foreach помещает в эту переменную первый элемент массива (в нашем примере это число 1). Выполняется тело цикла warn $el; — это выводит значение на экран. Цикл foreach помещает в переменную $el следующее значение из массива, опять выполняется тело цикла. Так повторяется пока тело цикла не будет выполнено для всех элементов массива.

Пройтись по массиву с помощью цикла for

Вот программа-пример, как пройтись по Perl массиву с помощью цикла похожего на цикл в языке Си:

▶ Run
#!/usr/bin/perl

my @arr = (1, 2, 3);

for (my $i = 0; $i < @arr; $i++) {
    warn $arr[$i];
}

Что тут происходит. Есть массив @arr. Дальше мы создали новую переменную $i и присвоили ей значение 0 (0 — это индекс первого элемента в Perl массиве). Дальше выполняется тело цикла warn $arr[$i];. После этого переменная $i с помощью оператора ++ увеличивается на один. После этого выполняется проверка условия $i < @arr. Если условие вернуло истину, то тогда все повторяется.

Это решение несколько сложнее чем решение с помощью foreach. Нужно аккуратно работать с граничными значениями. Если неправильно написать проверку, то можно либо пропустить последнее значение, либо обратиться к несуществующему элементу за последним элементом массива (такое обращение вернет undef).

Вот пример программы, которая работает тот же так же, но используется другое условие for:

▶ Run
#!/usr/bin/perl

my @arr = (1, 2, 3);

for (my $i = 0; $i <= $#arr; $i++) {
    warn $arr[$i];
}

for массив имеет смысл использовать если вам в теле цикла нужно не только значение элемента, но и его номер. Но и в этом случае можно использовать foreach цикл, вручную выставляя значение переменной с индексом:

▶ Run
#!/usr/bin/perl

my @arr = (1, 2, 3);
my $i = 0;

foreach my $el (@arr) {
    warn "index: $i value: $el";
    $i++;
}

Такой вариант проще воспринимается человеком и он менее подвержен багам с граничным значением. Но существует более удобная возможность сказать то же самое с помощью each.

Пройти по массиву с помощью while и each

Ключевое слово each используется не то чтобы очень часто, но почти всегда когда оно используется, оно используется для работы с хешом. Малоизвестно, но each можно использовать для того чтобы пройти по массиву, одновременно получая индекс элемента и сам элемент. Вот как выглядит предыдущий код, написанный с помощью each:

▶ Run
#!/usr/bin/perl

my @arr = (1, 2, 3);

while (my ($i, $el) = each @arr) {
    warn "index: $i value: $el";
}

each стало можно применять к массивам начиная с версии Perl 5.12. Если выполнить этот код на более ранней версии Perl, то будет ошибка:

Type of arg 1 to each must be hash (not private array) at script.pl line 5, near "@arr) "
Execution of script.pl aborted due to compilation errors.

Связанные темы

Другие статьи

Комментарии