【问题标题】:Perl multi hash from list列表中的 Perl 多哈希
【发布时间】:2015-01-18 06:47:45
【问题描述】:

我有一个列表,其中包含一些连接的值。我需要使用列表中的键和值创建一个哈希图并合并在一起。但我真的不知道该怎么做。

输入:

my @in =( 
'mgenv/1_2_3/parent.dx_environment',
'mgenv/1_2_3/doc/types.dat');

预期输出:

"{ $env => { $ver => [ $file1, $file2, ... ] } }" 

我试过这些:

(1)

my @sack_files = (
    'mgenv/1_2_3/parent.dx_environment',
    'mgenv/1_2_3/doc/types.dat');
    my $sack_tree = {};
    my %hash=();

    for( my $i=0; $i<scalar @sack_files; $i++){
        my @array = split(/[\/]+/,$sack_files[$i]);

        for(my $i=0;$i<(scalar @array)-1;$i++){
            my $first = $array[$i];
            my $second = $array[$i+1];
            $hash{$first}=$second;
            }

            # merge
    }

(2)

use Data::Dumper;

my @sack_files = (
    'mgenv/1_2_3/parent.dx_environment',
    'mgenv/1_2_3/doc/types.dat',
);

my $sack_tree = {};
my %hash=();

for( my $i=0; $i<scalar @sack_files; $i++){
    my @array = split(/[\/]+/,$sack_files[$i]);
    nest(\%hash,@array);

}

在第二种情况下,我得到一个错误,因为当循环变量 i=1 时,键/值已经存在,所以也许我必须检查以前添加的键/值。但我真的不知道怎么做。 我真的很感激任何想法。

【问题讨论】:

  • 所以您的预期结果是一个哈希图,其中键 = 第一个路径组件,值 = 其他哈希图,而键 = 第二个路径组件,值 = 文件列表?在第二个示例中,文件为 doc/types.dat ?

标签: arrays perl list data-structures hashmap


【解决方案1】:

只需使用push 将新成员添加到散列散列中的现有数组中。您必须使用 @{ ... } 取消引用数组引用。

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

use Data::Dumper;

my @sack_files = qw( mgenv/1_2_3/parent.dx_environment
                     mgenv/1_2_3/doc/types.dat
                     mgenv/1_2_3/doc/etc.dat
                     mgenv/4_5_6/parent.dx_environment
                     mgenv/4_5_6/doc/types.dat
                     u5env/1_2_3/parent.dx_environment
                     u5env/1_2_3/doc/types.dat
                     u5env/4_5_6/parent.dx_environment
                     u5env/4_5_6/doc/types.dat
                  );
my %hash;

for my $sack_file (@sack_files) {
    my ($env, $ver, $file) = split m{/}, $sack_file, 3;
    push @{ $hash{$env}{$ver} }, $file;
}

print Dumper \%hash;

输出

$VAR1 = {
  'mgenv' => {
    '1_2_3' => [
      'parent.dx_environment',
      'doc/types.dat',
      'doc/etc.dat'
    ],
    '4_5_6' => [
      'parent.dx_environment',
      'doc/types.dat'
    ]
  },
  'u5env' => {
    '4_5_6' => [
      'parent.dx_environment',
      'doc/types.dat'
    ],
    '1_2_3' => [
      'parent.dx_environment',
      'doc/types.dat'
    ]
  }
};

【讨论】:

  • 简单且解释清楚...对于那些跟随并在家阅读此内容的人 ;-) 成语:push @{ ... } 是 OP 中(虚构)功能“nest”的替代品. :-)
  • 很难为出色的答案添加任何内容 :-) 能够在一个语句 (push @{ $hash{$env}{$ver} }, $file;) 中将 push 值放入嵌套在哈希内的匿名数组中,您很快就会开始喜欢很多:思维导图开始将@{...}push 关联起来,并且嵌套了[] - 毕竟,@{ ... } 是 Perl 的最佳实践! :-) 对于 5.20 和 use experimental 'postderef'push $hash{$env}{$ver}-&gt;@* , $file; 也是一个选项。
猜你喜欢
  • 2012-09-09
  • 2015-01-17
  • 2011-06-10
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多