2016-01-12 2 views
1

Я пытаюсь распечатать размер моего массива. Я выполнил несколько других вопросов, подобных этому в стеке, но я никогда не получаю результат, который я хочу.Count perl array size

Все, что мне нужно в этом примере, это значение 3 для печати, поскольку у меня есть 3 индекса. Все я получаю от обоих методов печати является 0.

my @arr; 

$arr{1} = 1; 
$arr{2} = 2; 
$arr{3} = 3; 

my $size = @arr; 

print $size; # prints 0 

print scalar @arr; # prints 0 

Что я делаю не так, и как я могу получить общий размер массива при объявлении & населен таким образом?

+4

И если вы используете '$ arr [1] = 1;'. и т.д? * Всегда * 'использовать строгий; использовать предупреждения; '! – Biffen

+0

Хороший пункт о строгом и предупреждениях. Я все еще хотел бы задать вопрос, как я могу получить результат подсчета, когда объявляется с помощью '{}' вместо '[]'? –

+9

Что послужило для вас строгим и предупреждающим? Что-то о недостающем '% arr', возможно? '$ arr {1}' изменяет '% arr', а не' @ arr'. Вам придется придерживаться синтаксиса Perl. – Biffen

ответ

15

Во-первых:

my @arr; 

$arr{1} = 1; 
$arr{2} = 2; 
$arr{3} = 3; 

нонсенс. {} для хеш-ключей, поэтому вы имеете в виду %arr не @arr. use strict; и use warnings; сказали бы вам об этом, и это всего лишь один крошечный фрагмент, почему они считаются обязательными.

Чтобы подсчитать элементы в массиве, просто обращайтесь к нему в скалярном контексте.

print scalar @arr; 

if ($num_elements < @arr) { do_something(); } 

Но вы должны изменить свою вещь

my @arr; 

$arr[1] = 1; 
$arr[2] = 2; 
$arr[3] = 3; 

И примечание - первый элемент вашего массива $arr[0] будет неопределенным.

$VAR1 = [ 
      undef, 
      1, 
      2, 
      3 
     ]; 

В результате, вы получите результат 4. Чтобы получить желаемое «количество элементов» вы должны отфильтровать неопределенные элементы, с чем-то вроде grep:

print scalar grep {defined} @arr; 

Этот возьмет @arr с фильтром grep (возвращается 3 элемента), а затем возьмет скалярное значение - количество элементов, в этом случае 3.

Но обычно - вы не сделали бы этого. Это необходимо только потому, что вы пытаетесь вставить значения в определенные «слоты» в вашем массиве.

Что бы вы сделали, чаще всего, является использование либо прямое назначение:

my @arr = (1, 2, 3); 

Или:

push (@arr, 1); 
push (@arr, 2); 
push (@arr, 3); 

, который вставляет значения в конец массива.Вы бы - если явно итерация - перейти от 0..$#arr но вы редко должны сделать это, когда вы можете сделать:

foreach my $element (@arr) { 
    print $element,"\n"; 
} 

Или вы можете сделать это с помощью хэш:

my %arr; 

$arr{1} = 1; 
$arr{2} = 2; 
$arr{3} = 3; 

Это превращает ваш массив в множество пар (неупорядоченный) ключ-значение, которые вы можете получить доступ с keys %arr и сделать точно такой же:

print scalar keys %arr; 
if ($elements < keys %arr) { do_something(); } 

В этом последнем случае, ваш хэш будет:

$VAR1 = { 
      '1' => 1, 
      '3' => 3, 
      '2' => 2 
     }; 

Я бы предположил, что это плохая практика - если вы заказали значения, инструментом для задания является массив. Если у вас есть «ключевые» значения, хэш, вероятно, является инструментом для задания - например, «идентификатор запроса» или аналогичный. Обычно вы можете сказать разницу, глядя на то, как вы получаете доступ к данным, и есть ли пробелы (в том числе от нуля).

Так, чтобы ответить на ваш вопрос, как спросил:

my $size = @arr; 
print $size; # prints 0 
print scalar @arr; # prints 0 

Они не работают, потому что вы никогда не вставляйте какие-либо значения в @arr. Но у вас есть хэш, называемый %arr, который вы создали неявно. (И снова - use strict; и use warnings; сказали бы вам это).

+1

Вместо того, чтобы показывать им, как «grep» выводить неопределенные элементы, я думаю, что имеет смысл просто показать им, как заполнить массив, начиная с нуля индекса. Я могу просто представить их, используя этот 'grep' каждый раз, когда они создают новый массив, потому что Perl имеет эту« странную ошибку », которая всегда ставит неопределенный элемент в начале массивов. – ThisSuitIsBlackNot

+0

Хорошо, я буду расширять его. – Sobrique

2

Вы инициализируете хэш, а не массив.

Чтобы получить «размер» вашего хеша, вы можете написать.

my $size = keys %arr; 
0

Я просто подумал, что там должна быть иллюстрацией коды запуска с USUW (используйте строгое/предупреждение использования) и то, что он добавляет к процессу поиска и устранения неисправностей:

use strict; 
use warnings; 

my @arr; 
... 

И когда вы запустите его:

Global symbol "%arr" requires explicit package name (did you forget to declare "my %arr"?) at - line 9. 
Global symbol "%arr" requires explicit package name (did you forget to declare "my %arr"?) at - line 10. 
Global symbol "%arr" requires explicit package name (did you forget to declare "my %arr"?) at - line 11. 
Execution of - aborted due to compilation errors. 

Так USUW.

0

Вы можете думать, что вы инстанцировании элемент @arr, когда вы набираете в следующем коде:

$arr{1} = 1; 

Однако вы инстанцировании хэш делает это. Это говорит мне, что вы не используете строгую или у вас будет ошибка. Вместо этого перейдите в скобки, например:

$arr[1] = 1;