Perl数据结构遍历 - 引用跟随键 [英] Perl data structure traversal -- reference followed key

查看:155
本文介绍了Perl数据结构遍历 - 引用跟随键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

结果:许多行 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆