Perl中数组元素的计数

Perl中数组元素的计数,perl,arrays,count,Perl,Arrays,Count,如何获取数组中的项目总数,而不是最后一个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…打印标量grep{defined$\u}@a 也许你想要一个散列(或者另外一个)。数组是一组有序的元素;如果

如何获取数组中的项目总数,而不是最后一个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…

打印标量grep{defined$\u}@a

也许你想要一个散列(或者另外一个)。数组是一组有序的元素;如果创建
$foo[23]
,则通过
$foo[22]
编辑:散列与数组

正如cincodenada在评论中正确指出的那样,ysth给出了一个更好的答案:我应该用另一个问题来回答你的问题:“你真的想使用Perl数组吗?哈希可能更合适。”

数组为所有可能的索引分配内存,直到目前为止使用的最大索引。在您的示例中,您分配了24个单元格(但仅使用3个)。相比之下,散列只为实际使用的字段分配空间

数组解决方案:标量grep

以下是两种可能的解决方案(请参见下面的说明):

说明:在添加
$a[23]
之后,您的数组实际上包含24个元素——但其中大多数元素未定义(计算结果也为false)。您可以计算已定义元素的数量(如第一个解决方案中所做的)或真实元素的数量(第二个解决方案)

有什么区别?如果将
$a[10]=0
,则第一个解决方案将对其进行计数,但第二个解决方案不会(因为0为false,但已定义)。如果设置
$a[3]=undef
,则所有解决方案都不会将其计算在内

哈希解决方案(通过yst)

正如另一个解决方案所建议的,您可以使用哈希并避免所有问题:

$a{0}  = 1;
$a{5}  = 2;
$a{23} = 3;
print scalar(keys %a), "\n";  # prints 3
此解决方案计算零和未定义值。

听起来您需要一个新的值。普通数组中有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;
#/usr/bin/perl
严格使用;
使用警告;
我的%稀疏;
@稀疏{0,5,23}=(1..3);
打印“有”,标量键%sparse,“稀疏数组中的项\n”,
映射{“\t$sparse{$\}\n”}排序{$a$b}键%sparse;
标量上下文中的
keys
函数将返回稀疏数组中的项数。使用散列模拟稀疏数组的唯一缺点是,如果键的顺序很重要,则必须在迭代键之前对它们进行排序

您还必须记住使用函数从稀疏数组中删除项(仅将其值设置为undef是不够的)

Perl中的表达式总是为其上下文返回适当的值


例如,数组的“名称”如何?在列表上下文中,它给出元素列表。但是在标量上下文中,它返回数组中的元素数。

说明:perl并没有grilix想要的“稀疏”数组。如果您说“my@a;$a[10]=5;”,那么perl将创建一个包含11个条目的数组:前10个条目用“undef”填充,第11个条目用“5”填充。“scalar@a”和“$#a”报告始终是总长度/最后一个索引。kcwu过滤数组以只计算定义的条目。它可以工作,但不好。grep函数是O(n),这意味着如果你有@a[1,1\u 000\u 000]=(1,2);然后,它必须查看1000000个项目中的每一个,以获得一个计数,这也意味着您将无缘无故占用大量内存,使用散列代替。耶。。如果我必须使用数组,它是有效的,但我想我可以使用哈希来代替。不管怎样,他只是回应了我的要求。谢谢大家,可以吗?但是没有“编辑:”、“更新:”,或者类似的内容——答案应该看起来像是今天写的。这是正确的。但是,Tie::IxHash是可选的;在你的例子中,这似乎是不必要的。此外,无需提供谓词进行排序,因为这是默认值。“排序键%sparse”同样有效。哎呀,Tie::IxHash是从另一个示例中遗留下来的。让我删除它。@spolson No默认排序是词法排序而不是数字排序,因此键(1、2和10)将被排序(1、10、2)。此代码存在严重问题。首先,如果数组中的项包含空格,则它将被破坏。其次,它对整个数组项集迭代一次,对已定义项集迭代两次。第三,与所有基于阵列的解决方案一样,它无法区分未定义的用户集和阵列中的空插槽(这一个可能不坏,取决于代码的使用方式)。答案的最后一部分是正确的。grillix似乎来自PHP背景。PHP所称的“数组”实际上更类似于Perl的哈希,后者应该在类似的情况下使用。如何在Perl中将这一思想扩展到多维数组?对grep格式的小修改:
print scalar(grep{$}@a),“\n”
@arikin:我添加了一个逗号来解决语法问题。谢谢你指出!
#!/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;
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;
@people = qw( bob john linda ); 
$n = @people; # The number 3
Print " The number in the list is $n \n";