Помимо уже изученных скалярных данных, в
Итак,
(256, 512, 1024, 2048, 4096) # список из 5 чисел
('John', 'Paul', 'George', 'Ringo') # список из 4 строк
("Perl", 5.8) # список из строковых и числовых значений
Для записи списка текстовых строк, состоящих из одного слова, предусмотрена специальная форма списочного qw (сокращение от
qw(это очень удобно) # вместо ('это', 'очень', 'удобно')
qw/John Paul
George Ringo/ # список слов, расположенный на 2 строках
Элементами списочного
('One', $x, $x+$y-$z, 2*5) # список литералов и выражений
() # пустой список
Списочный
начальное_значение .. конечное_значение
В списочном
5 .. 10 # возвратит список (5, 6, 7, 8, 9, 10) 5.3 .. 7.1 # возвратит список (5.3, 6.3), т. к. 7.3 > 7.1 7 .. 5 # возвратит пустой список (), т. к. 5 < 7 $m .. $n # диапазон, заданный значениями от $m до $n
Если операция
(-2 .. 2) # список чисел (-2, -1, 0, 1, 2)
(25, 53, 77 .. 79) # список (25, 53, 77, 78, 79)
('A'..'Z','a'..'z') # список заглавных и строчных букв
($start .. $finish) # список значений от $start до $finish
Если списочный
($a, $b, $c) = (10 .. 12); # $a = 10; $b = 11; $c = 12; ($day, $month, $year) = (18, 12, 1987); # день рождения Perl ($m, $n) = ($n, $m); # поменять местами значения $n и $m
Если в списке слева от знака
($hh, $mm, $ss, $ms) = (10, 20, 30); # $ms не определено
Если в левой части
($hh, $mm, $ss) = (10, 20, 30, 400); # 400 отброшено
Если в левой части
$scalar = (10, 20, 30, 400); # то же, что $scalar = 400;
Значение списка может храниться в переменной, называемой
@variable # массив для хранения списка $variable # скаляр для хранения строки или числа
Списочное значение помещается в
@empty = (); # пустой массив после присвоения пустого списка @months = (1 .. 12); # массив со списком номеров месяцев @days = qw(Пн Вт Ср Чт Пт Сб Вс); # массив дней недели @week = @days; # копирование значения массива @days в @week @array = 25; # литерал 25 рассматривается как список (25) ($first) = @array; # в $first скопируется 1-й элемент массива @first = @second = (1, 2, 3); # каскадное присваивание
Если в левой части :
$array_size = @months; # число элементов (размер) массива $array_size = scalar @months; # размер массива
В зависимости от localtime возвращает разные значения: в скалярном
$date_and_time = localtime; ($sec, $min, $hour, # секунды, минуты, часы $mday, $mon, $year, # день, месяц, год, $wday, $yday, $isdst) # день недели, день года, часовая зона = localtime;
В состав списочного
@small = (3, 4, 5); # этот массив будет вставлен в список @big = (1, 2, @small, 6 .. 9); # то же, что @big = (1 .. 9); @big = ((1, 2), (3 .. 5), (6 .. 9)); # то же, что и выше
С помощью списка можно легко добавить новые элементы в начало или в конец существующего массива:
@array = ($new_element, @array); # добавить элемент в начало @array = (@array, $new_element); # добавить элемент в конец @all = (@first, @second); # объединить два массива в один
Присваивая
($element1, @array) = @array; # извлечь элемент из начала
(@array,$a,$b) = (1,2,3,4,5); # все 5 чисел попадут в @array
Элементы массива - это
@array # переменная-массив, хранящая список $array[0] # первый элемент массива с индексом 0 $array[1] # второй элемент массива с индексом 1 $array[$i] # i-й элемент массива, считая с 0 $array # скаляр, не имеющий отношения к массиву @array
Если требуется обращаться к элементам массива, начиная с последнего, то используются отрицательные значения индексов:
$array[-1] # последний элемент, то есть 1-й от конца $array[-2] # предпоследний элемент, то есть 2-й от конца $array[-$n] # n-й элемент массива, считая с конца
Индекс последнего элемента массива, который всегда на единицу меньше размера массива, можно узнать, указав специальный
$last_index = $#array; # индекс последнего элемента @array
Так, например, можно выбрать элемент массива с помощью встроенного , который возвращает дробное число от 0 до числа, указанного ему в качестве
$random_element = $array[int(rand($#array))];
В $#
В
$birthday[0] = 18; $birthday[1] = 12; $birthday[2] = 1987; ($birthday[0], $birthday[1], $birthday[2]) = (18, 12, 1987);
(Хотя более естественно для подобного @birthday[0, 1, 2] = (18, 12, 1987), но о срезах пойдет речь чуть позже в этой лекции.)
Если попытаться присвоить значение элементу с индексом больше текущего размера массива,
$birthday[5] = 'Perl'; # размер @birthday теперь 5 # значение $birthday[3] и $birthday[4] не определено
При попытке обратиться к элементу массива с несуществующим индексом будет возвращено
$array[$#array+100] # неопределенно
При использовании в качестве индекса массива дробного числа будет взята его целая часть, то есть $ рассматривается как $.
Часто требуется последовательно перебрать все элементы массива, от первого до последнего, для обработки или вывода их значений. Это можно сделать вполне традиционным образом, с помощью цикла for, как это записывается в языках C или
for (my $i = 0; $i < scalar @array; $i++) {
print "$array[$i] ";
}
, в котором все элементы массива поочередно совмещаются с указанной скалярной переменной. Эта переменная на время выполнения цикла становится синонимом очередного элемента массива, поэтому ее значение доступно не только для чтения, но и для изменения. Только что приведенный пример можно переписать так:
foreach my $element (@array) { # $element это синоним
print "$element "; # очередного элемента $array[$i]
}
Можно то же самое записать еще более кратко с помощью модификатора , который поочередно перебирает все элементы массива, рассматривая специальную переменную $_ как $_ совмещается с очередным элементом массива):
print "$_ " foreach @array;
Так что каждый
Обратите внимание, что значения элементов массива, будучи обычными скалярами, интерполируются в строках, заключенных в двойные кавычки. Целые массивы тоже интерполируются, если имя массива появляется в строке, обрамленной двойными кавычками. При этом значения элементов массива разделяются символом, хранящимся в специальной переменной $" (по умолчанию - пробелом). Вот еще один способ напечатать значения всех элементов массива, разделяя их двоеточиями:
$" = ':'; # установим разделитель элементов print "@array";
С помощью индексов можно обращаться не только к элементам массива, но и к
$fifth = (10..15)[5]; # то же, что $fifth = 15;
Обращение по индексу к элементу в списке
$hex = (0..9,'A'..'F')[$dec]; # при $dec==12 в $hex будет 'C'
Подобным же образом удобно обращаться к элементу списка, возвращаемого функцией. Например, так можно извлечь день месяца, зная, что у него 3-й индекс в результирующем списке функции localtime:
$month_day = (localtime)[3]; # элемент списка с индексом 3
В
@array[0,1] # то же, что ($array[0], $array[1]) @array[5..7] # то же, что ($array[5],$array[6],$array[7]) @array[3,7,1] # то же, что ($array[3],$array[7],$array[1]) @array[@indexes] # срез, заданный массивом индексов @array[5] # список ($array[5]), а не скаляр $array[5]
С помощью срезов удобно одновременно манипулировать значениями нескольких элементов, находящихся в любом месте массива:
# присвоить значения пяти элементам: @array[5..9] = qw(FreeBSD Linux MacOS NetWare Windows); # поменять местами значения 1-го и последнего элементов: @array[0,-1] = @array[-1,0]; # напечатать элементы с индексами от $start до $finish print @array[$start .. $finish];
Срезы могут применяться не только к массивам, но и к любым спискам, в том числе литеральным.
Для работы с таким популярным . Она удаляет из массива первый элемент, возвращая его значение. Когда
$first = shift @array; # извлечь первый элемент в $first # синоним: ($first, @array) = @array;
С помощью этой функции можно организовать цикл обработки массива, который закончится после извлечения из него последнего элемента, например:
while (my $first = shift @array) { # пока @array не опустеет
print "Обработан элемент $first.";
print "Осталось ", scalar @array, " элементов\n";
}
Обратите внимание, что для вывода текущего размера массива нужно использовать потому, что иначе воспримет @ как функция unshift, которая вставляет свои
unshift @array, $e1,$e2,$e3; # вставить значения в начало # синоним: @array = ($e1,$e2,$e3, @array);
С помощью массива можно организовать , которая добавляет элементы в конец массива:
push @stack, $new; # добавить элемент в конец массива # синоним: @stack = (@stack, $new);
Для извлечения одного значения из стека служит , которая удаляет последний элемент массива, возвращая его значение:
$last = pop @stack; # изъять последний элемент массива
При помощи комбинации функций и можно организовать
Для удаления или замены подсписка в массиве можно использовать функцию , которая удаляет идущие подряд элементы массива, заданные индексом первого элемента и количеством удаляемых элементов, и заменяет их новым списком (если он указан), возвращая
@array = (1..7); # исходный массив $offset = 2; $size = 4; # смещение и размер удаляемого списка @deleted = splice @array, $offset, $size, qw(новый список); # в @array теперь (1, 2, 'новый', 'список', 7) # в @deleted попали 4 удаленных элемента (3, 4, 5, 6)
Если $ в количестве $ элементов просто удаляется.
Операция , которая, не изменяя своего
@unsorted = (12, 1, 128, 2, 25, 3, 400, 53); @sorted = sort @unsorted; # в @sorted будет (1, 12, 128, 2, 25, 3, 400, 53)
Если нужно упорядочить <=>, например:
@sorted = sort {$a <=> $b } @unsorted;
# в @sorted будет (1, 2, 3, 12, 25, 53, 128, 400)
В блоке сравнения переменные $a и $b содержат значения двух текущих сравниваемых элементов. Для выполнения {$b <=> $a }. Помните, что для {$b . Вместо блока можно вызвать пользовательскую
, возвращающая
@array = qw(Do What I Mean); # исходный список
@backwards = reverse @array; # остается неизменным
# в @backwards будет ('Mean', 'I', 'What', 'Do')
Вложенный
@backwards = reverse(sort(@array));
# в @backwards будет ('What', 'Mean', 'I', 'Do')
Обратите внимание, что во всех приведенных примерах по желанию программиста или , программист может легко решать весьма нетривиальные задачи. Это подтверждает короткая программа на :
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"; # результат: А Л О К О Н Е Ц Н А Ч
Функция
@result = map ВЫРАЖЕНИЕ, СПИСОК @result = map БЛОК СПИСОК
Она вычисляет выражение или блок для каждого элемента списка и возвращает
@result = map $_*10, (11, 32, 55); # работа со списком # в @result будет (110, 320, 550)
При работе $_ локально устанавливается как $_ приводит к изменению соответствующего элемента массива. Таким способом можно изменять значения элементов массива. В этом примере воспользуемся блоком, куда поместим
@array = (11, 32, 55); # исходный массив
@result = map {if ($_ > 20) {$_*=10;} else {$_;} } @array;
# в @result будет (11, 320, 550)
, которая преобразует каждый
@array = (5..10); # объединяемый список $delimiter = ':'; # разделитель элементов списка в строке $string = join $delimiter, @array; # объединение в строку # теперь $string содержит '5:6:7:8:9:10'
Обратную операцию разделения строки по образцу на . Она разделяет строку по указанному разделителю и возвращает
$string = '5:6:7:8:9:10'; # исходная строка
$delimiter = ':'; # разделитель подстрок
$limit = 3; # число элементов
@strings = split $delimiter, $string, $limit; # разделение
# в @strings содержится ('5', '6', '7:8:9:10')
Функция имеет гораздо больше возможностей, о которых будет сказано в лекции, посвященной perldoc (после флага -f указывается имя искомой функции):
perldoc -f split
Рассмотренные ранее операции могут вести себя иначе, если они применяются не в скалярном, а в списочном
@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";
@stdin = <>; # считать все строки и поместить их в массив
print "Вы ввели ", scalar @stdin, " значений.\n";
Операция <> вводит строки полностью, включая завершающий символ chomp удаляет символы
chomp @stdin; # убрать \n в конце всех элементов массива $n_count = chomp $string; # убрать \n в конце строки
Похожая функция chop отсекает любой последний символ у строки (в скалярном
$last_char = chop $string; # отсечь последний символ строки chop @array; # отсечь последний символ в элементах массива
Если нужно избавиться только от символов chomp более безопасно, поскольку она никогда не удаляет значащие символы в конце строки.
При выполнении
@ARGV аргументы командной строки для выполняемой программы @INC список каталогов для поиска внешних Perl-программ @_ массив параметров для подпрограмм или буфер для split
Рассмотренные в этой лекции материалы по работе со списками и массивами предоставляют программисту мощные и выразительные средства эффективной обработки больших объемов данных. Обобщением идеи массивов стали ассоциативные массивы, которые будут рассмотрены в следующей лекции.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.