首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何创建具有列表列表形式的值的Perl散列

如何创建具有列表列表形式的值的Perl散列
EN

Stack Overflow用户
提问于 2019-08-05 19:41:37
回答 2查看 897关注 0票数 1

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

散列中预期的最终数据如下所示:

代码语言:javascript
复制
%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))
}

我想将它们保存为散列,以便更容易地查找和捕获重复的键

代码语言:javascript
复制
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行的示例文件上执行时,我得到的输出如下所示:

代码语言:javascript
复制
$VAR1 = {
       'key 1' => 2,
       'key 2' => 2,
       'key 3' => 2
    };

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

EN

回答 2

Stack Overflow用户

发布于 2019-08-05 20:14:07

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

代码语言:javascript
复制
my %hash = ( key => [ [ 'A', 'B', 'C' ], [ 1, 2, 3 ], [ 'Q', 'R', 'F' ] ] ...

请注意数组引用的方括号。

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

代码语言:javascript
复制
$ 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
        };
票数 2
EN

Stack Overflow用户

发布于 2019-08-05 20:03:23

我不是为你的问题提供答案,而是给出你输出的原因。这是因为“隐式标量转换”,它存储数组的长度。例如,

代码语言:javascript
复制
my @ar = qw(1 2 3 4);
my $x = @ar;
# output 4 (total length of array)

使用引用将数据保存在散列中,如下所示

代码语言:javascript
复制
use Data::Dumper;

my %hash;

my @array = (1,2,3,1);

@{$hash{"key"}} = @array;


print Dumper \%hash;

然后,您必须了解Perl中的数组扁平化,让我们考虑一下

代码语言:javascript
复制
@ar = ((1,2,3),(4,5,6),(3,4,5));
print $ar[0];
# output is 1 not (1,2,3) this is because array flatten

如果您想再次以数组格式访问数据,则必须将其存储为引用

代码语言:javascript
复制
my @ar = ( [1,3,4] , [5,4,2] );

print @{$ar[0]};
#1,3,4 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57357893

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档