我有一个散列的数组声明如下:
my %hash; push @{ $hash{ $value1[$_] } }, [ $value1[$_], $value2[$_], $value3[$_], $value4[$_], $value5[$_] ] for 0 .. $#value1;我希望能够使用以下方式检查每个键的值:
open KEYS, '>keys.txt' or die "Can't write to 'keys.txt'\n"; for my $key ( sort keys %hash ) { print KEYS "Key: $key contains the values: "; for my $value ( @{$hash{$value1}} ) { print KEYS "$value "; } print KEYS "\n"; } close(KEYS);虽然我可以使用Data :: Dumper可视化键和相关值,但上述代码的输出会为每个键提供内存位置,而不是数值。 例如:
Key: 'Value1' contains the values: ARRAY(0x7fcd8645ba68)即使我将相同数量的值推送到每个阵列上,每个键都包含不同数量的值
我正在做这件事的方式有什么问题吗?
I've got a hash of arrays that's declared as follows:
my %hash; push @{ $hash{ $value1[$_] } }, [ $value1[$_], $value2[$_], $value3[$_], $value4[$_], $value5[$_] ] for 0 .. $#value1;I want to be able to inspect the values for each key using:
open KEYS, '>keys.txt' or die "Can't write to 'keys.txt'\n"; for my $key ( sort keys %hash ) { print KEYS "Key: $key contains the values: "; for my $value ( @{$hash{$value1}} ) { print KEYS "$value "; } print KEYS "\n"; } close(KEYS);While I can visualise the keys and associated values using Data::Dumper, the output from the above code gives memory locations, rather than values, for each key. E.g:
Key: 'Value1' contains the values: ARRAY(0x7fcd8645ba68)Even though I'm pushing the same number of values onto each array, each key contains different numbers of values
Is there something wrong with the way I'm going about this?
最满意答案
首先,在你的内部循环中,你有
for my $value ( @{$hash{$value1}} ) { print KEYS "$value "; }什么是$value1 ? 我想你想用$key 。 始终use strict; use warnings use strict; use warnings来警告未定义的值和未声明的变量。
接下来,让我们看看当我们做什么时会发生什么
my %hash; push @{ $hash{ $value1[$_] } }, "(value$_)" for 0 .. $#value1;相反,即我们只是将一个字符串推送到散列中的arrayref上。 然后,输出看起来有点像
Key: Value1 contains the values: (value0) Key: Value2 contains the values: (value1) Key: Value3 contains the values: (value2)啊哈! 无论我们推到那个arrayref上是如何打印出来的。 如果你推送一个像[...]这样的匿名ARRAY(0x1234567)引用,你可以得到该引用的字符串: ARRAY(0x1234567) 。
您可能需要该arrayref的内容。 简单:只需解除引用。
...; print KEYS "[@$value] ";或类似的东西。 这里使用的"[...]"仅用于对输出进行可视化分组。
样式注释:
请考虑使用词法文件句柄open 3-arg:
my $filename = "keys.txt"; open my $keys, "<", $filename or die "Can't open $filename: $!";或使用自动错误处理:
use autodie; open my $keys, "<", "keys.txt";无论哪种方式,通常包含失败原因$!是很重要的$! 在错误信息中,或者它几乎是无用的。
根据您的喜好,您可以使用map和join来更优雅地使用代码,而不是使用循环。 我可能会把循环写成
use feature 'say'; for my $key ( sort keys %hash ) { say {$keys} "Key: $key contains the values: " . join " ", map { "[@$_]" } @{ $hash{$key} }; }First, in your inner loop, you have
for my $value ( @{$hash{$value1}} ) { print KEYS "$value "; }What on earth is $value1? I think you wanted to use $key. Always use strict; use warnings to get warned about undefined values and undeclared variables.
Next, let's take a look what happens when we do
my %hash; push @{ $hash{ $value1[$_] } }, "(value$_)" for 0 .. $#value1;instead, i.e. we just push a string onto the arrayref in the hash. Then, the output looks somewhat like
Key: Value1 contains the values: (value0) Key: Value2 contains the values: (value1) Key: Value3 contains the values: (value2)Aha! Whatever we push onto that arrayref is printed out as is. If you push an anonymous arrayref like [...], you get the stringification of that reference: ARRAY(0x1234567).
You probably want the contents of that arrayref. Easy: just dereference it.
...; print KEYS "[@$value] ";or something like that. The "[...]" are used here just to visually group the output.
Style notes:
Please consider 3-arg open with lexical filehandles:
my $filename = "keys.txt"; open my $keys, "<", $filename or die "Can't open $filename: $!";or use automatic error handling:
use autodie; open my $keys, "<", "keys.txt";Either way, it is usually important that you include the reason for the failure $! in the error message, or it is almost useless.
Instead of using loop, your code may be more elegant with map and join, depending on your taste. I would have probably written the loop as
use feature 'say'; for my $key ( sort keys %hash ) { say {$keys} "Key: $key contains the values: " . join " ", map { "[@$_]" } @{ $hash{$key} }; }更多推荐
发布评论