在将YAML-doc存储在hashref中之后,如何在perl中对其进行迭代



我必须处理一个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);

最新更新