Найти размер массива в 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 230

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

The раздел"типы переменных Perl" на документация perlintro содержит

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

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

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

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

The perldata documentation также охватывает в раздел"скалярные значения".

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

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) поскольку это угрожает аргументу как скалярному.