Perl数据结构遍历 - 引用跟随键 [英] Perl data structure traversal -- reference followed key
问题描述
结果:许多行 HASH(0x1948958)ARRAY(0x1978250)./directory/filename
结果: [第一个哈希的密钥] [第二个哈希的密钥] ./directory/filename#(数组的元素,当前工作)
Catch:应该进行N级结构,因此我试图使用Data :: Walk。
Catch: Should carry across to N level structures, hence my attempt at using Data::Walk.
我走路时我真正想做的该结构是引用正在使用的密钥。类似于Data :: Dumper,但是标签分隔而不是代码格式。我认为可能的解决方案(按照优先级顺序)是:
What I really want to do as I walk the structure is to reference the key that is being used. Kind of like Data::Dumper but tab-separated instead of in code format. I think the likely solutions (in order of preference) are:
- 有些调用DataWith Walk已被忽略。 li>
- 这个任务的一个更好的模块,我不知道。
- 一个快速的代码片段,我可以内联
- 我自己的Data :: Walk / Data :: Dumper(大皱眉)的模块/分支,将添加此功能。
use strict;
use File::Basename;
use Data::Walk;
my $files;
while (<>) {
chomp;
#ls -l output in a file; referencing filename from it (8th column)
my @line = split(/ /, $_, 8);
#fileparse exported by File::Basename
my ($name,$path) = fileparse($line[7]);
open (my $fh, '<', $path . $name);
my $sha = Digest::SHA->new('sha1');
$sha->addfile($fh);
#finding files by basename, then unique hash, then however many places it is stored.
#question not why I don't use the hash as the first field.
#basename digest path
push(@{$files->{$name}->{$sha->hexdigest}}, $path . $name);
}
my @val;
sub walkit {
$val[$Data::Walk::depth - 1] = $_;
if ($Data::Walk::depth == 3) {
print join("\t", @val), "\n";
}
}
&walk (\&walkit, %$files);
Gurus?
推荐答案
编辑:反对我更好的判断,我会再次回答这个问题。
Edit: against my better judgement, I'll try to answer this question again.
这是一个简单的方法打印您想要的使用Data :: Walk是不可行的,因为当你在一个哈希中时你没有键上下文(你只需要一个指向容器的指针。)
Here's a simple approach to print what you want. Using Data::Walk is not feasible because you don't have key context when you are inside a hash (you just get a pointer to the container.)
适用于有些复杂的结构。当然,如果你把函数引用或者是某些东西,那么它不会给出正确的输出。
This function works for somewhat complicated structures. Of course it will not give proper output if you put a function reference or something wonky in there.
use strict;
use warnings;
my $res;
sub walk {
my ($item, $path) = @_;
if (ref $item eq 'ARRAY') {
foreach (@$item) {
walk($_, $path);
}
} elsif (ref $item eq 'HASH') {
foreach (keys %$item) {
push @$path, $_;
walk($item->{$_}, $path);
pop @$path;
}
} else {
print join('-', @$path, $item), "\n";
}
}
my $struct = {
a => {
a1 => { a11 => [ 1, 2, 3 ] },
a2 => { a22 => [5, 6, 7] }
},
b => { b1 => [ 99 ], },
c => [ 100, 101, ],
d => [ 101, { d2 => { d3 => [200, 210] }, }, ],
};
walk $struct;
这篇关于Perl数据结构遍历 - 引用跟随键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!