我正在尝试从从文件读取的原始数据创建散列。每个hash元素的值将是一个列表列表。这些内部列表是从文件中解析出来的,需要作为关键字列表(( => 1),(列表2),……,(列表n))保存在散列中,以便进一步处理。
散列中预期的最终数据如下所示:
%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作为每个散列元素的值。请指出我做错了什么。
发布于 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中是扁平化的。哈希值必须是标量,您需要使用数组引用:
my %hash = ( key => [ [ 'A', 'B', 'C' ], [ 1, 2, 3 ], [ 'Q', 'R', 'F' ] ] ...请注意数组引用的方括号。
还要注意开头的圆括号:使用{创建一个散列引用,您可能不希望将其分配给散列。它将创建单个键的散列,如具有未定义的值的HASH(0x5653cc6cc1e0)。使用warnings应该会告诉您:
$ 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
};发布于 2019-08-05 20:03:23
我不是为你的问题提供答案,而是给出你输出的原因。这是因为“隐式标量转换”,它存储数组的长度。例如,
my @ar = qw(1 2 3 4);
my $x = @ar;
# output 4 (total length of array)使用引用将数据保存在散列中,如下所示
use Data::Dumper;
my %hash;
my @array = (1,2,3,1);
@{$hash{"key"}} = @array;
print Dumper \%hash;然后,您必须了解Perl中的数组扁平化,让我们考虑一下
@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如果您想再次以数组格式访问数据,则必须将其存储为引用
my @ar = ( [1,3,4] , [5,4,2] );
print @{$ar[0]};
#1,3,4 https://stackoverflow.com/questions/57357893
复制相似问题