我是perl的新手,我正在尝试建立一个相当简单的数据结构。我有几个循环在每次迭代时从数据库收集数据,我希望能够将这些数据存储在一个哈希映射数组中。
现在这就是我的困难所在:在数据收集循环之前有一个循环,只是构建一个将在集合循环中循环的名称列表。我在该循环中尝试做的是创建一个哈希映射数组,并将名称分配给地图中的字段,并将其他字段留空。
一旦完成,我如何为perl中数组中包含的地图内的项目赋值?
-----编辑看到我正在投票-----
my @characters;
for my $name (@names) {
my %flinstones = (
husband => $name,
pal => "",
);
push @characters, %flinstones;
}
现在如何在程序中设置pal字段?
答案 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