Найти размер массива в Perl - PullRequest
       0

Найти размер массива в Perl

233 голосов
/ 13 сентября 2011

Я, кажется, натолкнулся на несколько разных способов найти размер массива. В чем разница между этими тремя методами?

my @arr = (2);
print scalar @arr; # First way to print array size

print $#arr; # Second way to print array size

my $arrSize = @arr;
print $arrSize; # Third way to print array size

Ответы [ 11 ]

225 голосов
/ 13 сентября 2011

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

Второй способ фактически возвращает последний индекс массива, который (обычно) не совпадает с размером массива.

39 голосов
/ 13 сентября 2011

Во-первых, второе не эквивалентно двум другим. $#array возвращает последний индекс массива, который на единицу меньше размера массива.

Два других практически одинаковы. Вы просто используете два разных средства для создания скалярного контекста. Это сводится к вопросу читабельности.

Я лично предпочитаю следующее:

say 0+@array;          # Represent @array as a number

Я нахожу это яснее, чем

say scalar(@array);    # Represent @array as a scalar

и

my $size = @array;
say $size;

Последний выглядит довольно ясно в одиночку, как это, но я считаю, что лишняя строка лишает ясности, когда является частью другого кода. Это полезно для обучения тому, что @array делает в скалярном контексте, и, возможно, если вы хотите использовать $size более одного раза.

27 голосов
/ 13 сентября 2011

Получается размер путем принудительного помещения массива в скалярный контекст, в котором он оценивается как его размер:

print scalar @arr;

Это еще один способ принудительного ввода массива в скалярный контекст, поскольку онприсваивается скалярной переменной:

my $arrSize = @arr;

Получает индекс последнего элемента в массиве, так что на самом деле это размер минус 1 (при условии, что индексы начинаются с 0, что настраивается в Perl, хотя при этомобычно плохая идея):

print $#arr;

Последний вариант не очень хорош для получения размера массива.Было бы полезно, если вы просто хотите получить последний элемент массива:

my $lastElement = $arr[$#arr];

Кроме того, как вы можете видеть здесь при переполнении стека, эта конструкция не обрабатывается корректно большинством подсветчиков синтаксиса ...

6 голосов
/ 14 сентября 2013

Чтобы использовать второй способ, добавьте 1:

print $#arr + 1; # Second way to print array size
5 голосов
/ 23 октября 2013

Все три дают одинаковый результат, если мы немного изменим второй:

my @arr = (2, 4, 8, 10);

print "First result:\n";
print scalar @arr; 

print "\n\nSecond result:\n";
print $#arr + 1; # Shift numeration with +1 as it shows last index that starts with 0.

print "\n\nThird result:\n";
my $arrSize = @arr;
print $arrSize;
5 голосов
/ 12 июня 2013

Пример:

my @a = (undef, undef);
my $size = @a;

warn "Size: " . $#a;   # Size: 1. It's not the size
warn "Size: " . $size; # Size: 2
2 голосов
/ 09 мая 2017

Существуют различные способы печати размера массива. Вот значения всех: Допустим, наш массив my @arr = (3,4);

Метод 1: скаляр

Это правильный способ получить размер массивов.

print scalar @arr;  # prints size, here 2

Способ 2: порядковый номер

$#arr дает последний индекс массива. поэтому, если массив имеет размер 10, то его последний индекс будет 9.

print $#arr;     # prints 1, as last index is 1
print $#arr + 1; # Add 1 to last index to get array size

Мы добавляем 1 здесь, рассматривая массив как 0-indexed . Но, если он не основан на нуле, эта логика потерпит неудачу .

perl -le 'local $[ = 4; my @arr=(3,4); print $#arr + 1;'   # prints 6

Приведенный выше пример печатает 6, потому что мы установили его начальный индекс на 4. Теперь индекс будет 5 и 6, с элементами 3 и 4 соответственно.

Метод 3:

Когда массив используется в скалярном контексте, он возвращает размер массива

my $size = @arr;
print $size;   # prints size, here 2

На самом деле метод 3 и метод 1 совпадают.

2 голосов
/ 07 мая 2017

Из perldoc perldata , которое должно быть безопасно цитировать:

Следующее всегда верно:

scalar(@whatever) == $#whatever + 1;

Просто так долготак как вы не $ # независимо от ++ и таинственным образом увеличиваете размер или ваш массив.

Индексы массива начинаются с 0.

и

Вы можете обрезать массив до нуля, присвоив ему пустой список ().Следующие значения эквивалентны:

    @whatever = ();
    $#whatever = -1;

Что подводит меня к тому, что я искал, а именно к тому, как обнаружить, что массив пуст.Я нашел это, если $ # empty == -1;

2 голосов
/ 03 августа 2015

Раздел «Типы переменных Perl» документации perlintro содержит

Специальная переменная $#array сообщает вам индекс последнего элементамассива:

print $mixed[$#mixed];       # last element, prints 1.23

Возможно, вы захотите использовать $#array + 1, чтобы сообщить вам, сколько элементов в массиве.Не беспокойсяКак это бывает, использование @array, где Perl ожидает найти скалярное значение («в скалярном контексте»), даст вам количество элементов в массиве:

if (@animals < 5) { ... }

Документация perldata также описывает это в разделе «Скалярные значения» .

Если вы оцениваете массив в скалярном контексте, он возвращает длину массива.(Обратите внимание, что это не так для списков, которые возвращают последнее значение, такое как оператор запятой C, или для встроенных функций, которые возвращают то, что они хотят вернуть.) Следующее всегда верно:

scalar(@whatever) == $#whatever + 1;

Некоторые программисты предпочитают использовать явное преобразование, чтобы не оставлять никаких сомнений:

$element_count = scalar(@whatever);

Ранее в том же разделе описано, как получить индекс последнего элемента массива.

Длина массива является скалярным значением.Вы можете найти длину массива @days, оценив $#days, как в csh.Однако это не длина массива;это индекс последнего элемента, который имеет другое значение, поскольку обычно существует 0-й элемент.

1 голос
/ 13 марта 2018

А как насчет int(@array), поскольку это угрожает аргументу как скалярному.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...