迭代数据数组/哈希

时间:2011-10-26 01:10:35

标签: arrays perl hash

我希望遍历这些通过给定路径的数据结构(基本上是目录结构)。

目标是列出根/基本路径,然后列出所有子path(如果存在)以及存在的每个子path,列出file子路径。

我知道这可能需要通过HoH或AoH循环。有人能告诉我perl技术吗?感谢。

基础级别:/ work / eng / feeds

 $VAR1 = {
              'recursive' => 'no',
              'version' => '0.20.202.1.1101050227',
              'time' => '2011-10-26T00:20:18+0000',
              'filter' => '.*',
              'path' => '/work/eng/feeds',
              'directory' => [
                             {
                               'owner' => 'tst_act',
                               'group' => 'eng',
                               'permission' => 'drwxrwxr-x',
                               'path' => '/work/eng/feeds',
                               'accesstime' => '1970-01-01T00:00:00+0000',
                               'modified' => '2011-08-27T03:13:53+0000'
                             },
                             {
                               'owner' => 'tst_act',
                               'group' => 'eng',
                               'permission' => 'drwxr-xr-x',
                               'path' => '/work/eng/feeds/customer_care',
                               'accesstime' => '1970-01-01T00:00:00+0000',
                               'modified' => '2011-10-25T23:54:17+0000'
                             }
                           ],
              'exclude' => ''
            };

下一级:/ work / eng / feeds / customer_care

$VAR1 = {
          'recursive' => 'no',
          'version' => '0.20.202.1.1101050227',
          'time' => '2011-10-26T00:21:06+0000',
          'filter' => '.*',
          'path' => '/work/eng/feeds/customer_care',
          'directory' => [
                         {
                           'owner' => 'tst_act',
                           'group' => 'eng',
                           'permission' => 'drwxr-xr-x',
                           'path' => '/work/eng/feeds/customer_care',
                           'accesstime' => '1970-01-01T00:00:00+0000',
                           'modified' => '2011-10-25T23:54:17+0000'
                         },
                         {
                           'owner' => 'tst_act',
                           'group' => 'eng',
                           'permission' => 'drwx------',
                           'path' => '/work/eng/feeds/customer_care/abc',
                           'accesstime' => '1970-01-01T00:00:00+0000',
                           'modified' => '2011-10-25T17:12:56+0000'
                         },
                         {
                           'owner' => 'tst_act',
                           'group' => 'eng',
                           'permission' => 'drwx------',
                           'path' => '/work/eng/feeds/customer_care/def',
                           'accesstime' => '1970-01-01T00:00:00+0000',
                           'modified' => '2011-10-25T21:05:50+0000'
                         },
                         {
                           'owner' => 'tst_act',
                           'group' => 'eng',
                           'permission' => 'drwx------',
                           'path' => '/work/eng/feeds/customer_care/test',
                           'accesstime' => '1970-01-01T00:00:00+0000',
                           'modified' => '2011-10-25T21:28:14+0000'
                         }
                       ],
          'exclude' => ''
        };

还有一个级别:/ work / eng / feeds / customer_care / test(此处存在文件)

$VAR1 = {
          'recursive' => 'no',
          'version' => '0.20.202.1.1101050227',
          'time' => '2011-10-26T00:30:02+0000',
          'filter' => '.*',
          'file' => {
                    'owner' => 'tst_act',
                    'replication' => '3',
                    'blocksize' => '134217728',
                    'permission' => '-rw-------',
                    'path' => '/work/eng/feeds/customer_care/test/q_data_20111023.dat',
                    'modified' => '2011-10-26T00:29:46+0000',
                    'size' => '379085',
                    'group' => 'eng',
                    'accesstime' => '2011-10-26T00:29:46+0000'
                  },
          'path' => '/work/eng/feeds/customer_care/test',
          'directory' => {
                         'owner' => 'tst_act',
                         'group' => 'eng',
                         'permission' => 'drwx------',
                         'path' => '/work/eng/feeds/customer_care/test',
                         'accesstime' => '1970-01-01T00:00:00+0000',
                         'modified' => '2011-10-26T00:29:46+0000'
                       },
          'exclude' => ''
        };

2 个答案:

答案 0 :(得分:3)

这是一个启动者:

sub list_path_files {
    my ($data) = @_;

    say $data->{path}; # get value from a hashref

    my @directories;
    # check whether it is a single value or an arrayref of values
    if (ref $data->{directory} eq 'ARRAY') {
        @directories = @{ $data->{directory} }; # dereference the arrayref to get an AoH
    } else {
        @directories = $data->{directory}; # just get the single value
    }

    for my $dir (@directories) {
        next if $dir->{path} eq $data->{path};
        say $dir->{path};
    }

    # I'll leave the rest for you to do
}

<强>更新

要迭代hashref,首先需要取消引用,然后使用eachkeysvalues函数:

%hash = %$VAR1; # dereference

while (my ($key, $value) = each %hash) {...}

for my $key (keys %$VAR1) {
    my $value = $VAR1->{$key};
}

for my $value (values %$VAR1) {...}

如果哈希值是嵌套结构,您还需要取消引用哈希值:

if (ref $val eq '') {
    # $val is just a scalar - don't need to deref
}
elsif (ref $val eq 'HASH') {
    my %hash = %$val;
}
elsif (ref $val eq 'ARRAY') {
    my @array = @$val;
}

答案 1 :(得分:0)

由于数据中存在XML-esque时间戳,并且目录/文件结构是散列或哈希数组,我猜你要解析XML来构建初始哈希?

如果您正在使用XML :: Simple从XML中读取它,

ForceArray =&gt; ['目录','档案']

将避免检查ref类型。

然后你可以简化为这样的事情:

my %fs

for my $item (values %your_giant_hash_with_fs_data) {

    $fs{$_->{path}}='d' for ( @{ $item->{directory} } );
    $fs{$_->{path}}='f' for ( @{ $item->{file} } );

}

my $search_path='/work/eng/feeds/customer_care/test';
my $search=qr/^$search_path/;

for (sort keys %fs) {

    print "$fs{$_} $_\n" if /$search/;

}

输出:

d /work/eng/feeds/customer_care/test
f /work/eng/feeds/customer_care/test/q_data_20111023.dat

或者如果您不想创建临时结构

my $search_path='/work/eng/feeds/customer_care/test';
my $search=qr/^$search_path/;

{
    my %seen;
    for my $item (values %your_giant_hash_with_fs_data) {
        for my $type (qw/directory file/) {
            for ( @{ $item->{$type} } ) {

                if ( $_->{path}=~/$search/ and not $seen{$_->{path}} ) {

                    printf("%-10s%s\n",$type,$_->{path});
                    $seen{$_->{path}}=1;

                }

            }
        }
    }
}

这只适用于你的每条路径都是绝对的,绝对路径不能重复