我必须处理一个YAML文档:
sheet : filename.exe
book : bookname
characters :
- amy : mother
- mark : father
- dave : son
现在我有了以下代码,我想在其中迭代并将"字符"保存在哈希中以供以后使用:
use YAML qw(LoadFile);
my $config = LoadFile('config.yaml');
my %charlist = ();
foreach my $key (keys %$config){
next if ($key ne "character");
foreach my $list (keys %{$config{$key}}){
my $current_character = $config{$key}{$list};
$charlist->{$list} = $current_character;
}
}
我正试图将其存储为这样的散列:
{ amy => mother,
mark => father,
dave => son
}
我无法进入第二个前臂循环。我不能理解这个问题。
始终使用use strict; use warnings;
(或等效(。它会发现一些问题。
您的问题与YAML无关。这是关于导航由YAML生成的数据结构。因此,让我们从以下内容开始了解有关数据结构的更多信息:
use Data::Dumper;
print(Dumper($config));
我们得到:
$VAR1 = {
'sheet' => 'filename.exe',
'book' => 'bookname',
'characters' => [
{
'amy' => 'mother'
},
{
'mark' => 'father'
},
{
'dave' => 'son'
}
]
};
我们只关心$config->{characters}
,它是对数组的引用(如[]
所示(,所以我们将有以下形式的东西:
my %characters;
for (@{ $config->{characters} }) {
...
}
数组的每个元素都是一个包含单个字符的散列。我们可以使用%h = (%h, %extra);
将其合并到中
my %characters;
for my $character_container (@{ $config->{characters} }) {
%characters = ( %characters, %$character_container);
}
备选方案:
my %characters;
for my $character_container (@{ $config->{characters} }) {
@characters{ keys(%$character_container) } = values(%$character_container);
}
就是这样!
请注意,您的文件格式相当奇怪。应该是:
sheet : filename.exe
book : bookname
characters :
amy : mother
mark : father
dave : son
这提供
$VAR1 = {
'book' => 'bookname',
'characters' => {
'mark' => 'father',
'dave' => 'son',
'amy' => 'mother'
},
'sheet' => 'filename.exe'
};
解决方案变成
my $characters = $config->{characters};
好吧,也许你的问题毕竟与YAML有关:(
@toolic认可的使用
foreach my $key (keys %{ $config }) {
next if ($key ne "characters");
...$config->{$key}...
}
但这是一种特别糟糕的书写方式
if ( my $characters = $config->{$key} ) {
...$characters...
}
我们特别使用散列,以便能够通过它们的键来查找元素。对所有元素进行迭代以逐键查找是没有意义的。(我提请他们注意这一点,但他们保留了不良做法。(
如果您有use strict;
,您会看到几个编译错误。
我使用Data::Dumper
查看LoadFile
返回的结构,以便更容易地取消引用该结构。characters
存储为数组,而不是散列。您还尝试将config
作为hash而不是hashref进行访问。
此外,perldsc是理解参考文献的绝佳来源。
use warnings;
use strict;
use YAML qw(LoadFile);
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
my $config = LoadFile('config.yaml');
my %charlist;
foreach my $key (keys %{ $config }){
next if ($key ne "characters");
foreach my $list (@{ $config->{$key} }){
%charlist = (%charlist, %{ $list });
}
}
print Dumper(%charlist);