Perl数据结构

时间:2014-12-22 15:43:00

标签: perl

我是perl的新手,我正在尝试建立一个相当简单的数据结构。我有几个循环在每次迭代时从数据库收集数据,我希望能够将这些数据存储在一个哈希映射数组中。

现在这就是我的困难所在:在数据收集循环之前有一个循环,只是构建一个将在集合循环中循环的名称列表。我在该循环中尝试做的是创建一个哈希映射数组,并将名称分配给地图中的字段,并将其他字段留空。

一旦完成,我如何为perl中数组中包含的地图内的项目赋值?

-----编辑看到我正在投票-----

my @characters;
for my $name (@names) {
    my %flinstones = (
        husband   => $name,
        pal       => "",
    );
    push @characters, %flinstones;
}

现在如何在程序中设置pal字段?

3 个答案:

答案 0 :(得分:1)

我认为您的数据结构并不像您认为的那样有效 - 数组用于有序的项目序列。

散列用于一组无序的键值对。由于这个原因,在数组中嵌套哈希并不是那么平常。

你将要解决的问题是什么?推动'如果你把哈希视为一个数组,它实际上就像一个数组。在内部,他们是两个标量序列'并且关键的区别在于数组维护它的顺序,其中散列只是确保键和值之间的关系持续存在。

例如:

my @array = ( "husband", "fred", "pet", "" );
my %hash = @array;

foreach my $key ( keys %hash ) {
    print "$key = $hash{$key}\n";
}

这也是相反的:

@array = %hash;
print join (":", @array );

所以你正在做的是推进@characters ("husband", $name, "pal", "" )。这甚至不太可能成为你想做的事情。

首先关闭 - 将哈希值插入到数组中,需要输入哈希引用:

push @characters, \%flinstones;    ## ITYM flintstones

然后你就可以:

for my $character ( @characters ) {
   print $character -> {'husband'};
}

但我实际上并不认为结构符合您的要求,因此可能希望考虑采用面向对象的方法。

答案 1 :(得分:1)

Perl有三个基本的变量结构:Scalars变量($foo),Arrays(@foo)和Hashes(%foo)。

Perl允许您将引用用于这些结构。 引用是指向特定变量类型的指针。例如,我可以引用 Hash Array 。它使用引用来构建更复杂的结构。

重要的是要记住,这些更复杂的结构是引用,对于Perl中的新人来说可能很难理解。例如:

@foo = (1, 2, 3, 4);      # This is a standard array.
%foo = (1, 2, 3, 4);      # This is a hash with two items. 1 & 3 are keys. 2 & 4 data.
$foo = [1, 2, 3, 4];      # A reference to a nameless array that contains four items
$foo = {1, 2, 3, 4};      # A reference to a nameless hash that contains four items.

请注意,当我只是将括号更改为方括号或花括号时,我现在讨论的是引用而不是哈希或数组。另请注意,哈希可以在数组和哈希之间来回转换。

@foo = (1, 2, 3, 4);      # This is an array of four numbers
%foo = @foo;              # %foo is a hash with two data items  1=> 2 and 3 => 4
@bar = %foo;              # @bar is another array!

难怪Perl的新手会对此感到困惑!

让我们来看看那个循环:

my @characters;
for my $name (@names) {
    my %flinstones = (
        husband    => $name,
        pal        => "",
    );
    push @characters, %flinstones;   # What's this?
}

在你的@characters数组中,你推送的是四个项目的数组,而不是哈希值!

push正在使用%flinstones是一个数组上下文(好吧, list 上下文)。如果%flinstones

husband => Fred,
pal     => "",

推送将如下所示:

@characters = ( "husband", "Fred", "pal", "" );

下次执行时(假设$name更改为Barney),您会看到:

@characters = ("husband", "Fred", "pal", "", "husband", "Barney", "pal", "");

你基本上是用这个循环破坏你的哈希结构。不是你想要的。

你的意思是:

push @characters, \%flinstones;   # See the difference from the above?

%flinstones前面的反斜杠说你正在将引用推送到你的数组中的%flinstone哈希,而不是项目(包括键和值)你的阵列。一个小反斜杠会在程序中产生差异。更糟糕的是,两个push语句在语法上都是正确的。您的Perl程序将与任何一个一起运行。

难怪新的Perl用户发现引用令人困惑!

循环之后,你的数组看起来像这样:

$characters[0] = { husband => "Fred", pal => "" };
$characters[1] = { husband => "Barney", pal => "" };

请注意,花括号谈论哈希引用!请注意,这种方式有一个哈希引用数组,并保存哈希结构。您可以pop关闭每个哈希引用(并记住它是引用!)或者说$character[0]->{husband}设置为Fred

我强烈建议您阅读Perl Tutorial on References。我还建议您查看Data::Dumper模块。您可以使用此工具打印出复杂的数据结构,看看发生了什么。

顺便说一下,你通常会看到像这样的东西哈希哈希。想象一下,不是使用@characters数组,而是使用由该字符的第一个名称键入的%characters哈希:

my %characters;
$character{Fred}   = {};   #Some hash reference. We'll fill it out later...
$character{Barney} = {};
$charcater{Wilma}  = {};
$character{Betty}  = {};

现在,我们可以谈谈每个角色!让我们填写一些字段:

$character{Fred}->{spouse}   = "Wilma";
$character{Fred}->{pal}      = "Barney";
$character{Barney}->{spouse} = "Betty";
$character{Barney}->{pal}    = "Fred";
$character{Betty}->{spouse}  = "Barney";
$character{Betty}->{pal}     = "Wilma";

所以,我们有一个哈希,每个条目都是一个子哈希(对另一个哈希的引用),它包含两个条目(一个用于spouse,一个用于pal。我们可以使用这个跟踪复杂关系的结构。

事实上,人们可能不止一个人。让pal指向数组!

$characher{Fred}->{pal} = [];  This is an array reference!
push @{ $character{Fred}->{pal} }, ("Barney", "Joe");

现在,$character{Fred}有两个朋友!请注意解除引用语法将_array引用($character{Fred}->{pal})转换回数组,这样我就可以将项目推入其中。

阅读教程。这很简单,然后玩弄参考,直到你更好地了解正在发生的事情。还要记住,引用和散列需要引用取消引用,并且您使用的数据分组参数类型(括号,花括号或方括号)可以使你是在谈论一个引用,一个数组或哈希,甚至是你正在谈论的引用类型,这是一个很大的区别。

答案 2 :(得分:0)

我避免使用数组的哈希/哈希数组,花一点时间研究如何在Perl中执行OO。它预先做了一点点工作,但可以进一步节省维护难题。您可以man perlboot或查看在线perl OO tutorial