这是我的问题:
我有一个像数据结构这样的文件系统:
%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")
。
因此,因为输入的长度是变化的,所以我不知道如何访问散列的值。有什么想法吗?
答案 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接受一个数组。它还为您提供了一个带有辅助方法的对象,并处理跨平台的斜杠问题。
答案 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;
}