在Perl中查找数组的长度

时间:2012-12-06 13:31:45

标签: perl

我有一些代码:

my %hosts = (
    'USAmazon' => ['US','CA'],
    'EUAmazon' => ['GB', 'FR', 'IT', 'ES', 'DE'],
    'CNAmazon' => ['CN'],
    'JPAmazon' => ['JP'],
);

my @values = $hosts{$ARGV[0]};

我看到$values[0][0]持有美国,$values[0][1]持有CA.为什么会这样?请解释一下。

另外,如何找出$values[0]的长度?

scalar $values[0]打印出类似ARRAY(0x12FFc) blah..blah ......

的内容

任何链接也都有帮助。

4 个答案:

答案 0 :(得分:5)

你是Perl中的新手,你已经点击引用 ......

在Perl中,有三种标准类型的数据:

  • 标量:这些可以包含单个值,例如$foo
  • 数组:这些可以包含值的列表。数组有一个顺序(此值在数组中早于此值),并且根据数组中的顺序(从第0个项到最后一个项)引用值。您将数组称为@foo,将单个项称为$foo[1]
  • 哈希:这些是键控值。每个值都有一个唯一键。没有订单,但您可以根据其密钥快速找到值。您将散列称为%foo,将单个项称为$foo{BAR}

请注意,所有这些都包含单个值。数组或散列的每个元素只能有一个值。例如,我有一台主机(USAmazonEUAmazon等),我希望每个主机与一个国家/地区相关联($host{USAmazon} = 'US';,{{1} GB`等)。这很简单,很容易在Perl中实现。

不幸的是,事实并非如此。每台主机都可以与国家代码的整个阵列相关联。如何将整个可能的国家/地区代码放入主机的哈希? 这是引用的地方。想象一下,我有一个国家代码列表。如果我能找到该列表的内存位置,我可以将该内存位置用作哈希中的引用。因此,我的哈希包含每个键的单个值。只是关键是内存中特定列表的位置。

这就是引用的含义,以及为什么有时会看到$host{EUAmazon} =之类的值。这恰好是存储在哈希中的某个数组的内存位置。

在引用上有一个很好的Perl tutorial,它实际上是标准Perl发行版的一部分。这是一个很好的起点。

快速基本指南,但是......

  • 只需在其前面添加一个反斜杠,即可获得对Perl变量类型的引用:

例如:

ARRAY(0x12FFc)

如果我打印$reference_to_foo_array = \@foo; ,我会收到类似$reference_to_foo_array的内容,告诉我这是内存位置ARRAY(0x12FFc)的数组。但是,我现在可以将整个数组0x12FFc存储到单个散列或数组元素中:

@foo
  • 如果我有一个引用,我可以通过在它前面放置正确的变量类型符号将其转换回Perl变量。这称为解除引用

例如:

$some_array[0] = $reference_to_foo_array;

在很多情况下,我可以消除花括号:

@another_array = @{$reference_to_foo_array};

我可以拥有非常复杂的物体。例如。我有一个哈希的人,每个哈希包含一个手机类型的哈希。每种电话类型都包含该类型的电话列表。例如,我可能有两个工作电话号码和两部手机:

@another_array = @$reference_to_foo_array;

这是指DAVID的手机。但是,这实际上是手机类型的哈希。如果我打印出来,我会得到类似 $person{DAVID}; 的内容:

如果我想要特定的手机类型,我会这样做:

Hash(0x12b23)

这是David的手机号码列表。如果我打印这个,我会得到像 ${$person{DAVID}}{CELL}; 这样的东西,因为它是一个电话号码数组的参考。

这是指DAVID的第一部手机:

Array(0x3458b)

没有括号,你会看到:

${${$phone{DAVID}}{CELL}}[0];

幸运的是,Perl的语法糖更容易阅读:

$$$phone{DAVID}{CELL}[0];

这表示有一个哈希(人)指的是另一个哈希(电话类型)引用一组电话号码。

Perl还有一种创建哈希或数组的方法,而无需实际命名。这会创建一个匿名哈希:

$phone{DAVID}->{CELL}->[0];

现在,我可以为DAVID提供一些手机类型。以下是我创建匿名数组的方法:

$phone{DAVID} = {};

现在,我可以获得DAVID的手机号码列表。

还有一些事情:

  • 查看模块Data::Dumper。这有助于您打印出这些非常复杂的数据类型的结构,并帮助您了解您正在查看的内容。

  • 查看Perl函数ref。这可以帮助你弄清楚你在看什么。例如:

    我的$ data_type = ref $ phone {DAVID} - > {CELL}

会将$phone{DAVID}->{CELL} = []; 设置为$data_type。这让我知道ARRAY不是电话号码,而是电话号码列表(或者可能是其他参考类型的列表)。

答案 1 :(得分:3)

数组和哈希值始终是标量。在这种情况下,对于现有元素,$hosts{$ARGV[0]}是包含对数组的引用的标量。您需要取消引用该引用以获取该数组。

my $length = @{ $hosts{$ARGV[0]} };

答案 2 :(得分:0)

%hosts哈希将数组引用保存为值。 你只需要取消引用它们:

my @values = @{$hosts{$ARGV[0]}};

答案 3 :(得分:-1)

有关

my @values = $hosts{$ARGV[0]};

其中$ARGV[0]是您的哈希的键之一,例如'USAmazon'%hosts哈希中的相应值将为

['US','CA']

这是一个匿名数组引用。此结构[ LIST ]用于创建要用作标量值的数组引用,例如:

my $foo = [ 1, 2, 3 ];    # $foo is a scalar

如果您要从现有阵列中进行此操作,您也可以这样做:

my @foo = (1, 2, 3);      # @foo is an array
my $foo = \@foo;          # reference to an array @foo

但是,这将生成指向数组的硬编码链接。使用匿名数组不会。

在散列(或数组)中,值只能是标量值。因此,如果将哈希值分配给数组,则将为数组中的第一个元素分配该标量值。数组的第一个元素当然是$array[0]。所以:

my $foo = $hosts{$ARGV[0]};   # [ 'US', 'CA' ]
my @bar = $foo;
print $bar[0];                # prints the array reference ARRAY(...)
print $foo;                   # same thing
print $foo->[0];              # 'US'
print $bar[0][0];             # 'US' (same thing)

有关详细信息,请参阅perldoc perldata