重新整理特定格式的哈希

时间:2019-01-14 10:39:43

标签: perl

%files_data = {                                                                                                                                                                                                                                     

              './GetOpt.pm' => {
                          'pid' => {
                                     '56061' => 1,
                                     '56065' => 1
                                   }
                            },
              'file1' => {
                          'pid' => {
                                     '56061' => 2
                                   }
                        },
              'file2' => {
                         'pid' => {
                                    '56065' => 2
                                  }
                       },
              './src/bin/perl' => {
                            'pid' => {
                                       '56061' => 1,
                                       '56065' => 1
                                     }
                          }
                    };

%process_data = (

          '56061' => {
                       'parent' => 'NA',
                       'name' => 'file1'
                     },
          '56069' => {
                       'parent' => '56065',
                       'name' => 'echo Hello_file1'
                     },
          '56062' => {
                       'parent' => '56061',
                       'name' => 'echo Hello_file2'
                     },
          '56065' => {
                       'parent' => '56061',
                       'name' => 'file2'
                     }
        );

我想遍历$files_data哈希,并为每个文件获取文件链。 因此,我将获得以下哈希值:

%hash = (
        'file1' => {
            '/src/bin/perl' => 1,
            'file2' => { 
                '/src/bin/perl' => 1,
                './GetOpt.pm' => 1
            },
            './GetOpt.pm' => 1,
    }
);

我需要遵循pid链,直到每个文件的主要父级('NA')。

最有效的解决方法是什么?我需要一些有关如何实施的指导。

编辑:以'./GetOpt.pm'文件为例。它有一个pid 56061,因此我们转到%process_data并看到'file1'(它是一个文件)。此外,我们看到56061的父级是NA,所以我们停下来并得到:

file1 => ./GetOpt.pm

但是./GetOpt.pm还有一个pid-56065,所以我们转到56065并看到file2(它是一个文件)。然后,转到具有56061(是s文件)的file1。这样我们得到:

file1 => file2 => ./GetOpt.pm

将其合并:

file1 => {
    ./GetOpt.pm,
    file2 => ./GetOpt.pm
}

我想构建一个流程文件链(仅包含文件)。 %files_data包含有效文件,%process_data包含我们需要遵循的流程层次结构

1 个答案:

答案 0 :(得分:1)

我使用了一个递归子例程,该例程将文件名链添加到现有哈希中。我必须通过在.之前加上/src/bin/perl来修正您的预期结构。

#!/usr/bin/perl
use warnings;
use strict;

my %files_data = (
    './GetOpt.pm'    => {pid => {56061 => 1,
                                 56065 => 1}},
    'file1'          => {pid => {56061 => 2}},
    'file2'          => {pid => {56065 => 2}},
    './src/bin/perl' => {pid => {56061 => 1,
                                 56065 => 1}}
);

my %process_data = (
    '56061' => {'parent' => 'NA',
                'name' => 'file1'},
    '56069' => {'parent' => '56065',
                'name' => 'echo Hello_file1'},
    '56062' => {'parent' => '56061',
                'name' => 'echo Hello_file2'},
    '56065' => {'parent' => '56061',
                'name' => 'file2'}
);

my %expected = (
    'file1' => {
        './src/bin/perl' => 1,
        'file2' => {
            './src/bin/perl' => 1,
            './GetOpt.pm' => 1
        },
        './GetOpt.pm' => 1,
    }
);

use Test::More;
use Test::Deep;

sub hashify {
    my ($tree, @chain) = @_;
    my $head = shift @chain;
    $tree->{$head} = @chain ? {} : 1 unless ref $tree->{$head};
    hashify($tree->{$head}, @chain) if @chain;
}

sub add {
    my ($tree, $key) = @_;
    for my $pid (keys %{ $files_data{$key}{pid} }) {
        my @chain = $key;
        while ($pid ne 'NA') {
            my ($parent, $name) = @{ $process_data{$pid} }{qw{ parent name }};
            unshift @chain, $name unless $name eq $chain[0];
            $pid = $parent;
        }
        hashify($tree, @chain);
    }
}

my $result = {};
add($result, $_) for keys %files_data;

cmp_deeply($result, \%expected);
done_testing();