简体   繁体   English

Perl 中的数组元素计数

[英]Counting array elements in Perl

How do I get the total items in an array, NOT the last id?如何获取数组中的总项目数,而不是最后一个 id?

None of two ways I found to do this works:我发现的两种方法都不起作用:

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

I expected to get 3...我希望得到3...

Edit: Hash versus Array编辑:哈希与数组

As cincodenada correctly pointed out in the comment, ysth gave a better answer: I should have answered your question with another question: "Do you really want to use a Perl array? A hash may be more appropriate."正如 cincodenada 在评论中正确指出的那样,ysth 给出了更好的答案:我应该用另一个问题回答你的问题:“你真的想使用 Perl 数组吗?散列可能更合适。”

An array allocates memory for all possible indices up to the largest used so-far.数组为所有可能的索引分配内存,直到迄今为止使用的最大索引。 In your example, you allocate 24 cells (but use only 3).在您的示例中,您分配了 24 个单元格(但仅使用了 3 个)。 By contrast, a hash only allocates space for those fields that are actually used.相比之下,散列只为那些实际使用的字段分配空间。

Array solution: scalar grep数组解决方案:标量grep

Here are two possible solutions (see below for explanation):这里有两种可能的解决方案(见下文解释):

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

Explanation: After adding $a[23] , your array really contains 24 elements --- but most of them are undefined (which also evaluates as false).说明:添加$a[23] ,您的数组确实包含 24 个元素 --- 但其中大部分是未定义的(也被评估为 false)。 You can count the number of defined elements (as done in the first solution) or the number of true elements (second solution).您可以计算已定义元素的数量(如第一个解决方案中所做的那样)或真实元素的数量(第二个解决方案)。

What is the difference?有什么区别? If you set $a[10]=0 , then the first solution will count it, but the second solution won't (because 0 is false but defined).如果您设置$a[10]=0 ,那么第一个解决方案会计算它,但第二个解决方案不会(因为 0 是假的但已定义)。 If you set $a[3]=undef , none of the solutions will count it.如果您设置$a[3]=undef ,则没有任何解决方案会计算它。

Hash solution (by yst)哈希解决方案(由 yst)

As suggested by another solution, you can work with a hash and avoid all the problems:正如另一个解决方案所建议的那样,您可以使用哈希并避免所有问题:

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

This solution counts zeros and undef values.此解决方案计算零和 undef 值。

It sounds like you want a sparse array .听起来您想要一个稀疏数组 A normal array would have 24 items in it, but a sparse array would have 3. In Perl we emulate sparse arrays with hashes:普通数组有 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;

The keys function in scalar context will return the number of items in the sparse array.标量上下文中的keys函数将返回稀疏数组中的项数。 The only downside to using a hash to emulate a sparse array is that you must sort the keys before iterating over them if their order is important.使用散列模拟稀疏数组的唯一缺点是,如果键的顺序很重要,则必须在对键进行迭代之前对其进行排序。

You must also remember to use the delete function to remove items from the sparse array (just setting their value to undef is not enough).您还必须记住使用delete函数从稀疏数组中删除项目(仅将它们的值设置为 undef 是不够的)。

Maybe you want a hash instead (or in addition).也许你想要一个散列(或另外)。 Arrays are an ordered set of elements;数组是一组有序的元素; if you create $foo[23] , you implicitly create $foo[0] through $foo[22] .如果您创建$foo[23] ,则通过$foo[22]隐式创建$foo[0] $foo[22]

打印标量 grep { 定义 $_ } @a;

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

Expressions in Perl always return the appropriate value for their context. Perl 中的表达式总是为其上下文返回适当的值。

For example, how about the “name” * of an array?例如,数组的“名称” * 怎么样? In a list context, it gives the list of elements.在列表上下文中,它给出元素列表。 But in a scalar context, it returns the number of elements in the array.但在标量上下文中,它返回数组中的元素数。

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM