如何在foreach循环中正确取消引用哈希?

时间:2015-06-07 04:25:45

标签: perl hash

我想以下列方式打印我创建的哈希的内容: $dataStore{"$items1"}{"$items2"}{"$items3"}{'counts'}[0] = 534;

编辑:我忘了添加上面的变量是从while循环中的文件读入的,但我把它留了出来,因为它可以根据Data :: Dumper输出正常工作。

基本上,我正在创建一个以数组结尾的嵌套哈希结构。我的程序使用上面的方法将值输入到数组的不同位置。

使用Data :: Dumper我可以看到这是正常的。

$VAR1 = {
    'items1' => {
        'items2' => {
            'items3' => {
                'counts' => [
                    '534'
                ]
...

然而,问题是我想使用foreach循环打印结构。主要是因为这是我知道的唯一方式。

我的foreach循环看起来像这样,没有太多格式化:

foreach my $item1 (sort keys %dataStore) {
    print "$item1\n";
    foreach my $item2 (sort keys $dataStore{"$item1"}) {
        print "%$item2\n";
        foreach my $item3 (sort keys $dataStore{"$item1"}{"$item2"}) {
            print "%$item3\n";
            print join (', ', @{$dataStore{"$item1"}{"$item2"}{"$item3"}})
        }
    }
}

结果看起来像这样(我已经匿名化了数据):

item1
item2
item3
HASH(0x2c10dc0)item3
HASH(0x2b1dc70)item3
HASH(0x295bbd8)item3
HASH(0x2c34fb8)item3
HASH(0x2cca6a0)item3
HASH(0x2ba5ef0)item3
HASH(0x28fcb58)item3
HASH(0x2cca760)item3

根据我到目前为止所读到的内容,我认为我的问题是我错误地取消引用哈希,但我不确定。它可以像在错误的东西上调用print一样简单。我已经尝试了许多不同的方法来取消引用哈希,但我要么得到这样的结果,要么在perl之后截断结果抱怨foreach循环中的排序引用是“实验性的”。

我通过cygwin在Windows 8.1上使用Perl v5.20.1。

感谢。

3 个答案:

答案 0 :(得分:3)

我认为更好的方法是使用StoreData1.Write(text);代替这种方式。如果哈希中的级别增加,则需要一次又一次地更改此代码。此外,在某些时候,在这段代码中维护和写入更多内容几乎是不可能的。

您可以将此代码用于您的问题。此外,这可能没有太多优化,因此您可能需要这样做。但它会解决你的问题。

reference

我希望这能解决你的问题。

答案 1 :(得分:2)

确保use strictuse warnings,避免实验性自动解除引用是个不错的主意。您可以使用严格模式捕获代码中的几个运行时错误,例如,您尝试将items3取消引用到数组中,但它是一个hashref,其中键为'counts',然后是一个arrayref。

假设:

my $items1 = "items1";
my $items2 = "items2";
my $items3 = "items3";
my %dataStore = ();
$dataStore{"$items1"}{"$items2"}{"$items3"}{'counts'}[0] = 534;

然后:

foreach my $item1 (sort keys %dataStore) {
    foreach my $item2 (sort keys %{$dataStore{"$item1"}}) {
        print "%$item2\n";
        foreach my $item3 (sort keys %{$dataStore{"$item1"}{"$item2"}}) {
            print "%$item3\n";
            print join (', ', @{$dataStore{"$item1"}{"$item2"}{"$item3"}{'counts'}});
        }
    }
}

产地:

%items2
%items3
534

答案 2 :(得分:0)

这是一种使用递归子例程的方法:

#!/usr/bin/perl

use warnings;
use strict;

my $h = {'i1' => {'i2' => {'i3' => [534, 10, 99]}}};

sub deref {

    my $param = shift;

    for my $k (keys(%$param)){
        if (ref($param->{$k}) eq 'HASH'){
            print "$param->{$k}\n";

            # call this sub again with the next level of the hash
            # as a parameter, if it's another hashref

            deref($param->{$k});
        }
        elsif (ref($param->{$k}) eq 'ARRAY'){
            print "$_\n" for @{ $param->{$k} };
        }
    }
}

deref($h);