my @array = qw/Н А Ч А Л О К О Н Е Ц/; # исходный массив
my $i = 3; # сдвиг массива ВЛЕВО на 3 элемента
my $n = @array; # число элементов массива
# алгоритм сдвига Кена Томпсона (1971)
@array[0 ..$i-1] = reverse @array[0 .. $i-1];
@array[$i .. $n-1] = reverse @array[$i .. $n-1];
@array[0 .. $n-1] = reverse @array[0 .. $n-1];
print "@array\n"; # результат: А Л О К О Н Е Ц Н А Ч
Функция map позволяет выполнить действия над всеми элементами массива, поэтому ее нередко используют вместо цикла. У этой функции есть две формы вызова:
@result = map ВЫРАЖЕНИЕ, СПИСОК
@result = map БЛОК СПИСОК
Она вычисляет выражение или блок для каждого элемента списка и возвращает список результатов. С ее помощью, например, можно выполнить арифметическое действие над всеми элементами списка:
@result = map $_*10, (11, 32, 55); # работа со списком
# в @result будет (110, 320, 550)
При работе map специальная переменная $_ локально устанавливается как синоним текущего элемента списка, поэтому изменение переменной $_ приводит к изменению соответствующего элемента массива. Таким способом можно изменять значения элементов массива. В этом примере воспользуемся блоком, куда поместим операторы вычисления нового значения (если значение элемента больше 20, оно будет удесятеряться):
@array = (11, 32, 55); # исходный массив
@result = map {if ($_ > 20) {$_*=10;} else {$_;} } @array;
# в @result будет (11, 320, 550)
Список можно преобразовать в строку с помощью встроенной функции join , которая преобразует каждый элемент списка к строке, объединяет отдельные элементы списка в одну строку, вставляя между элементами указанный разделитель, и возвращает полученную строку в качестве результата. Например:
@array = (5..10); # объединяемый список
$delimiter = ':'; # разделитель элементов списка в строке
$string = join $delimiter, @array; # объединение в строку
# теперь $string содержит '5:6:7:8:9:10'
Обратную операцию разделения строки по образцу на список строк выполняет встроенная функция split . Она разделяет строку по указанному разделителю и возвращает список составляющих строк. Можно ограничить число разделяемых подстрок, тогда строка будет разделена не более, чем на это число элементов. Например:
$string = '5:6:7:8:9:10'; # исходная строка
$delimiter = ':'; # разделитель подстрок
$limit = 3; # число элементов
@strings = split $delimiter, $string, $limit; # разделение
# в @strings содержится ('5', '6', '7:8:9:10')
Функция split имеет гораздо больше возможностей, о которых будет сказано в лекции, посвященной регулярным выражениям. Подробно познакомиться с которыми можно из системной документации с помощью утилиты perldoc (после флага -f указывается имя искомой функции):
perldoc -f split
Пользовательские функции и процедуры, как встроенные функции, тоже могут обрабатывать списки: принимать списки параметров и возвращать список значений. Об этом будет подробнее рассказано в лекции 12 .
Рассмотренные ранее операции могут вести себя иначе, если они применяются не в скалярном, а в списочном контексте. Так, операция повторения (репликации), чаще всего применяемая к строкам, может также использоваться и для многократного повторения значений списка. Обратите внимание, что она работает именно со списками, поэтому если необходимо размножить значения массива, то его следует поместить в списочный литерал. Например:
@two = ('A', 'B') x 2; # будет: ('A', 'B', 'A', 'B')
@three = (@one) x 3; # в @three трижды повторится @one
С помощью операции повторения можно присвоить одинаковые значения всем элементам массива, например, сделать их неопределенными. Таким образом результат функции undef() можно повторить по числу элементов массива:
@array = (undef()) x @array; # или (undef) x scalar(@array)
При необходимости ввести данные в массив можно воспользоваться упомянутой ранее операцией ввода строк <>, читающей строки из входного потока. В скалярном контексте операция "кристалл" считывает одну строку в переменную. Вот так можно в диалоге ввести значения в массив из пяти строк:
for (@stdin = (), $n = 0; $n < 5; $n++) {
print 'Введите значение N ', $n+1, ':';
$stdin[$n] = <>; # считать строку в $n-й элемент массива
}
В списочном контексте "кристалл" читает в массив за одну операцию все строки файла. Например, так можно заполнить массив данными, вводимыми с консоли:
print "Введите значения - по одному в строке.",
"Для окончания ввода нажмите Ctrl-Z (или Ctrl-D).\n";
Читать дальше