【问题标题】:Printing values for hash of arrays in perl在 perl 中打印数组哈希值
【发布时间】:2013-06-24 21:02:36
【问题描述】:

我有一个声明如下的数组哈希:

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) 

即使我向每个数组推送相同数量的值,每个键包含不同数量的值

我的处理方式有问题吗?

【问题讨论】:

    标签: arrays perl hash key


    【解决方案1】:

    首先,在你的内部循环中,你有

    for my $value ( @{$hash{$value1}} ) {
        print KEYS "$value ";
    }   
    

    $value1到底是什么?我想你想使用$key。始终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)

    您可能想要该数组引用的内容。简单:只需取消引用即可。

    ...;
    print KEYS "[@$value] ";
    

    或类似的东西。此处使用"[...]" 只是为了对输出进行可视化分组。


    风格说明:

    请考虑带有词法文件句柄的 3-arg open

    my $filename = "keys.txt";
    open my $keys, "<", $filename or die "Can't open $filename: $!";
    

    或使用自动错误处理:

    use autodie;
    open my $keys, "<", "keys.txt";
    

    无论哪种方式,在错误消息中包含失败$!原因 通常很重要,否则几乎没用。

    不使用循环,使用mapjoin,您的代码可能会更优雅,这取决于您的喜好。我可能会把循环写成

    use feature 'say';
    for my $key ( sort keys %hash ) {
        say {$keys} "Key: $key contains the values: "
          . join " ", map { "[@$_]" } @{ $hash{$key} };
    }
    

    【讨论】:

      【解决方案2】:

      那是因为你推送的是一个数组引用而不是一个值列表。

      比较

      push @array, [ $foo ];
      

      push @array, $foo;
      

      @arrays 都包含一个元素,但前者包含一个包含 $foo 的数组引用,而后者仅包含 $foo

      如果您在第一个 push 参数之后丢失了方括号,那么您就可以开始了。

      【讨论】:

        猜你喜欢
        • 2012-07-22
        • 1970-01-01
        • 2016-02-21
        • 2017-09-30
        • 2020-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-09
        相关资源
        最近更新 更多