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

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

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 ответов


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

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


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

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

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

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

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

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

и

my $size = @array;
say $size;

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


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

print scalar @arr;

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

my $arrSize = @arr;

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

print $#arr;

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

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

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


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

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;

пример:

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

warn "Size: " . $#a;   # Size: 1. It's not the size
warn "Size: " . $size; # Size: 2

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

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

на раздел"типы переменных 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-й элемент.


существуют различные способы печати размер массива. Вот значения всех: Допустим, наш массив 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-проиндексированных. Но, если это не так с нуля то, эта логика будет не.

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 одинаковы.


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

всегда так:

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

до тех пор, пока вы не $#whatever++ и таинственным образом увеличить размер или Ваш массив.

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

и

вы можете усечь массив до нуля, назначив ему null list (). Ниже приведены эквивалент:

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

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


чтобы найти размер массива, используйте scalar ключевые слова:

print scalar @array;

чтобы узнать последний индекс массива, есть $# (переменная Perl по умолчанию). Он дает последний индекс массива. Поскольку массив начинается с 0, мы получаем размер массива, добавляя его в $#:

print "$#array+1";

пример:

my @a = qw(1 3 5);
print scalar @a, "\n";
print $#a+1, "\n";

выход:

3

3

насчет int(@array) как угрозы аргумент как скаляр.