如何使用Perl中Hashes of Hashes的循环获取某些值

时间:2016-06-15 09:02:46

标签: perl configuration-files

我有一个config.file来做一些测试,我也希望从这个获得一些值。

这是我的config.file:

my $folder = 'E:\FOLDER\Test\WEB';
{
       license => [ 'kit-licence.zip',
                    'kit-work.zip'
                   ],
       programs => [
             #template society =>\%program_work
             'VIKTOR DESCRIPTION PRODUCT' => { 
                    name => 'VIKTOR ', 
                    parameters => [
                           Count_id                           => '06 (Viktor)',
                           Birth_date                    => '1995-04-30',
                           Marriage_date              => '2014-05-26',
                           Divorce_date               => '2015-03-30',
                           Activities_folder               => $folder.'\VIKTOR\independent worker',
                           Activities_format               => 'Enterprise Format (V35)',
                           Description_File_from       => $folder.'\VIKTOR\FILE\description.xlm',

                    ] 
             },

             'OLIVER NEW OBJECT' => {   
                    name => 'OLIVER ', 
                    parameters => [
                           Count_id                           => '06 (oliver)',
                           Birth_date                    => '1990-04-30',
                           Marriage_date              => '2011-03-26',
                           Divorce_date               => '2014-01-30',
                           Activities_folder               => $folder.'\OLIVER\independent worker',
                           Activities_format               => 'Enterprise Format (V35)',
                           Description_File_from       => $folder.'\OLIVER\FILE\description.xlm',

                    ] 
             }, 
       ]
};

我的文件测试如下:

#test.pl
use Modern::Perl;
my $config = do 'work.conf';
use Data::Dumper;
say Dumper( $config );

例如,要在Program for Viktor中获取参数,我可以这样做:

 %programs = @{ $config->{programs} };
    for my $prog (values %programs) {
      my %param = @{ $prog->{parameters} };
      for my $name (sort keys %param){
       print $name, ': ', $param{$name},"\n";
      }
    }

但就我而言,我希望能够为每个用户获取参数。这里只是Viktor。我想为Oliver或其他用户获取它们。为此,为了区分所有用户,我必须使用“模板社会”这个名称来区分每个用户。例如,对于Viktor来说,它是:“VIKTOR DESCRIPTION PRODUCT”。对于奥利弗:“OLIVER NEW OBJECT”。

我该怎么做?

“许可证”也是如此:

 license => [ 'kit-licence.zip',
               'kit-work.zip'
                   ],
       programs => [..

我想通过每个人的名字获得许可证。例如,'kit-license.zip'。

而不是那样的“硬编码”:

use File::Spec::Functions qw/catfile/;
my $filename = catfile($::svn, ${$config->{license}}[0]);
my $filename1 = catfile($::svn, ${$config->{license}}[1]);

也许在一个循环中,但我没有找到。

PS:不要问我为什么他们都离婚了。我真的不知道。

1 个答案:

答案 0 :(得分:2)

您已经很好地将这些数组引用转换为哈希值。但values让你的生活变得艰难。您需要同时拥有密钥和值。您可以使用each来执行此操作。

my %programs = @{ $config->{programs} };
while (my ($template_society, $value) = each %programs ) {
    my %param = @{ $value->{parameters} };
    print "$template_society\n";
    for my $name ( sort keys %param ) {
        print "\t", $name, ': ', $param{$name}, "\n";
    }
}

这将产生以下输出:

VIKTOR DESCRIPTION PRODUCT
    Activities_folder: \VIKTOR\independent worker
    Activities_format: Enterprise Format (V35)
    Birth_date: 1995-04-30
    Count_id: 06 (Viktor)
    Description_File_from: \VIKTOR\FILE\description.xlm
    Divorce_date: 2015-03-30
    Marriage_date: 2014-05-26
OLIVER NEW OBJECT
    Activities_folder: \OLIVER\independent worker
    Activities_format: Enterprise Format (V35)
    Birth_date: 1990-04-30
    Count_id: 06 (oliver)
    Description_File_from: \OLIVER\FILE\description.xlm
    Divorce_date: 2014-01-30
    Marriage_date: 2011-03-26

each内置返回每次迭代的哈希的键和值,并且undef一旦完成。这就是您需要将其置于while循环中的原因。

如果您不喜欢each方法,也可以使用keys代替values来获取密钥($template_society)并将其用于查找适当的值。

my %programs = @{ $config->{programs} };
foreach my $template_society (keys %programs ) {
    my %param = @{ $programs{$template_society}->{parameters} };
    print "$template_society\n";
    for my $name ( sort keys %param ) {
        print "\t", $name, ': ', $param{$name}, "\n";
    }
}

这将为您提供相同的输出。

要获取所有许可证路径,您需要将它们存储在一个数组中,并使用循环将数组ref处理到该数组中。最简单,最简洁的方法是使用map

my @licences = map { catfile($::svn, $_ ) } @{ $config->{license} };

它就像一个foreach循环,只是更短。 BLOCK基本上是一个获取$_中当前迭代项的函数。它与以下内容基本相同,只是更加流行。

my @licences;
foreach my $licence (@{ $config->{license} } ) {
    push @licences, catfile($::svn, $licence );
}

不要尝试动态创建$foo1$foo2等变量。那样不行。 See this 1 解释原因。

最后关于$::svn的一句话:如果你在一个包中,你应该把你的代码放到一个函数中并接受$svn作为参数。使用来自不同包的全局变量或包变量是棘手和混乱的,你会在某些时候用它来射击自己。

1:正常文件目前已损坏,因此我使用archive.org获取