Подтвердить что ты не робот

Подсчет элементов массива в Perl

Как получить итоговые элементы в массиве, а не последний id?

Ни один из двух способов, которые я нашел для этого, не работает:

my @a;
# Add some elements (no consecutive ids)
$a[0]= '1';
$a[5]= '2';
$a[23]= '3';

print $#a, "\n"; # Prints 23
print scalar(@a), "\n"; # Prints 24

Я ожидал получить 3...

4b9b3361

Ответ 1

Изменить: Хэш против массива

Как правильно указал цинкадендада в комментарии, ysth дал лучший ответ: я должен был ответить на ваш вопрос другим вопросом: "Вы действительно хотите использовать массив Perl? Хеш может быть более уместным".

Массив выделяет память для всех возможных индексов до самого большого, используемого до сих пор. В вашем примере вы выделяете 24 ячейки (но используйте только 3). Напротив, хеш выделяет пространство для тех фактически используемых полей.

Решение массива: скалярная grep

Вот два возможных решения (см. ниже пояснение):

print scalar(grep {defined $_} @a), "\n";  # prints 3
print scalar(grep $_, @a), "\n";            # prints 3

Объяснение: После добавления $a[23] ваш массив действительно содержит 24 элемента --- но большинство из них undefined (также оценивается как false). Вы можете подсчитать количество определенных элементов (как это сделано в первом решении) или количество истинных элементов (второе решение).

В чем разница? Если вы установите $a[10]=0, то первое решение будет считать это, но второе решение не будет (потому что 0 является ложным, но определено). Если вы установите $a[3]=undef, ни одно из решений не посчитает это.

Решение хэша (по yst)

Как было предложено другим решением, вы можете работать с хешем и избегать всех проблем:

$a{0}  = 1;
$a{5}  = 2;
$a{23} = 3;
print scalar(keys %a), "\n";  # prints 3

Это решение подсчитывает значения нулей и undef.

Ответ 2

Похоже, вы хотите разреженный массив. Обычный массив имел бы 24 элемента в нем, но разреженный массив имел бы 3. В Perl мы эмулируем разреженные массивы с хешей:

#!/usr/bin/perl

use strict;
use warnings;

my %sparse;

@sparse{0, 5, 23} = (1 .. 3);

print "there are ", scalar keys %sparse, " items in the sparse array\n",
    map { "\t$sparse{$_}\n" } sort { $a <=> $b } keys %sparse;

Функция keys в скалярном контексте вернет количество элементов в разреженном массиве. Единственным недостатком использования хэша для эмулирования разреженного массива является то, что вы должны сортировать ключи перед их итерацией по ним, если их порядок важен.

Вы также должны помнить об использовании функции delete для удаления элементов из разреженного массива (просто установка их значения в undef не является достаточно).

Ответ 3

Возможно, вам нужен хеш вместо (или дополнительно). Массивы представляют собой упорядоченный набор элементов; если вы создаете $foo[23], вы неявно создаете $foo[0] через $foo[22].

Ответ 4

print scalar grep {defined $_} @a;

Ответ 5

@people = qw( bob john linda ); 
$n = @people; # the number 3
Print " le number in the list is $n \n"; 

Выражения в Perl всегда верните соответствующее значение для своего контекста. Например, как насчет "имени" * массив. В контексте списка он отображает список элементов. Но в скалярном контексте он возвращает количество элементов в массиве:

Ответ 6

sub uniq {
    return keys %{{ map { $_ => 1 } @_ }};
}
my @my_array = ("a","a","b","b","c");
#print join(" ", @my_array), "\n";
my $a = join(" ", uniq(@my_array));
my @b = split(/ /,$a);
my $count = $#b;