首页 > 解决方案 > 如何创建一个 Perl 哈希值作为列表的列表

问题描述

我正在尝试从从文件中读取的原始数据创建哈希。每个散列元素的值将是一个列表列表。这些内部列表是从文件中解析出来的,需要作为 key => ((list 1), (list 2), ......, (list n)) 保存在 hash 中以供进一步处理。

散列中预期的最终数据将类似于:

%hash = {
    'key 1' => ((A, B, C), (1, 2, 3), (Q, R, F)),
    'key 2' => ((X, Y, Z), (P, Q, R)),
    'key 3' => ((1.0, M, N), (R, S, T), (4, 7, 9)),
      ......,
    'key n' => ((5, M, 8), (J, K, L), (1, 3, 4))
}

我想将它们保留为哈希以便于查找并捕获重复的键

my %hash;
my @array = ();
my @inner_array = ();

open (my $FH, '<', $input_file) or die "Could not open : $!\n";

while (my $line = <$FH>) {
    chomp $line;

    ## Lines making up $key and @inner_array
    ## e.g. $key = 'key 1' and
    ## @inner_array = (A, B, C)
    ## @inner_array = (1, 2, 3)

    if (exists $hash{$key}) {         # We have seen this key before    
        @array = $hash{$key};         # Get the existing array 
        push(@array, @inner_array);   # Append new inner list 
        $hash{$key} = @array;         # Replace the original list

    } else {                  # Seeing the key for the first time
        @array = ();                  # Create empty list
        push (@array, @inner_list);   # Append new inner list 
        $hash{$key} = @array;         # Replace the original list
    }
}

close $FH;

print dumper %hash;

在 10 行的示例文件上执行时,我得到如下输出:

$VAR1 = {
       'key 1' => 2,
       'key 2' => 2,
       'key 3' => 2
    };

我没有看到一个数组数组,而是将标量值 2 作为每个散列元素的值。请建议我做错了什么。

标签: perl

解决方案


((A, B, C), (1, 2, 3), (Q, R, F))等价于(A, B, C, 1, 2, 3, Q, R, F),列表在 Perl 中被展平。哈希值必须是标量,您需要使用数组引用:

my %hash = ( key => [ [ 'A', 'B', 'C' ], [ 1, 2, 3 ], [ 'Q', 'R', 'F' ] ] ...

注意数组引用的方括号。

还要注意开头的圆括号: using{创建一个哈希引用,您可能不想将其分配给哈希。它会创建一个HASH(0x5653cc6cc1e0)带有未定义值的单个键的散列。使用警告应该告诉你:

$ perl -MData::Dumper -wE 'my %h = {x=>1}; say Dumper \%h'
Reference found where even-sized list expected at -e line 1.
$VAR1 = {
          'HASH(0x557d282e41e0)' => undef
        };

推荐阅读