使用数组寻址哈希散列

时间:2012-07-31 11:11:55

标签: perl perl-data-structures

这是我的问题:

我有一个像数据结构这样的文件系统:

%fs = (
    "home" => {
        "test.file"  => { 
            type => "file",
            owner => 1000, 
            content => "Hello World!",
        },
    },
    "etc"  => { 
        "passwd"  => { 
            type => "file",
            owner => 0, 
            content => "testuser:testusershash",
            },
        "conf"  => { 
            "test.file"  => { 
                type => "file",
                owner => 1000, 
                content => "Hello World!",
            },
        },
    },
);

现在,要获取/etc/conf/test.file我需要$fs{"etc"}{"conf"}{"test.file"}{"content"}的内容,但我的输入是一个数组,如下所示:("etc","conf","test.file")

因此,因为输入的长度是变化的,所以我不知道如何访问散列的值。有什么想法吗?

6 个答案:

答案 0 :(得分:5)

您可以使用循环。在每个步骤中,您将进一步深入到结构中。

my @path = qw/etc conf test.file/;
my %result = %fs;
while (@path) {
    %result = %{ $result{shift @path} };
}
print $result{content};

您也可以使用Data::Diver

答案 1 :(得分:1)

my @a = ("etc","conf","test.file");

my $h = \%fs;
while (my $v = shift @a) {
  $h = $h->{$v};
}
print $h->{type};

答案 2 :(得分:1)

与其他人给出的逻辑相同,但使用foreach

@keys = qw(etc conf test.file content);
$r = \%fs ;
$r = $r->{$_} foreach (@keys);
print $r;

答案 3 :(得分:0)

$pname = '/etc/conf/test.file';
@names = split '/', $pname;
$fh = \%fs;
for (@names) {
    $fh = $fh->{"$_"} if $_;
}
print $fh->{'content'};

答案 4 :(得分:0)

Path :: Class接受一个数组。它还为您提供了一个带有辅助方法的对象,并处理跨平台的斜杠问题。

https://metacpan.org/module/Path::Class

答案 5 :(得分:-1)

您可以构建哈希元素表达式并调用eval。如果将它包装在子程序中,这将更整洁

my @path = qw/ etc conf test.file /;

print hash_at(\%fs, \@path)->{content}, "\n";

sub hash_at {
  my ($hash, $path) = @_;
  $path = sprintf q($hash->{'%s'}), join q('}{'), @$path;
  return eval $path;
}
相关问题