2011-06-03 103 views
6

我坚持看起来像一个简单的概念问题给我。在Web上寻找类似的问题和Stack Overflow后,我找不到类似的东西,所以我想我可以问你。如何递归地嵌套散列数据结构?

我正在构建一个哈希散列这是深深嵌套的数据结构。深度可以是10-20倍。为了这个问题,我只列出了深度。

我无法在Perl中递归遍历下面的示例哈希。我也包含了我的代码。

它给了我下面的错误:

Can't use string ("1") as a HASH ref while "strict refs" in use at

只是所以很清楚:我的哈希必然有值1某些键我无法避免。

$VAR1 = { 
    'Eukaryota' => { 
     'Rhodophyta'   => {'count' => 5}, 
     'Alveolata'   => {'count' => 16}, 
     'stramenopiles'  => {'count' => 57}, 
     'count'    => 155, 
     'Glaucocystophyceae' => {'count' => 1}, 
     'Cryptophyta'  => {'count' => 18}, 
     'Malawimonadidae' => {'count' => 1}, 
     'Viridiplantae'  => {'count' => 57}, 
    }, 
    'Bacteria' => { 
     'Cyanobacteria'  => {'count' => 1}, 
     'Actinobacteria'  => {'count' => 4}, 
     'count'    => 33, 
     'Proteobacteria'  => {'count' => 25}, 
     'Deinococcus-Thermus' => {'count' => 2}, 
     'Firmicutes'   => {'count' => 1}, 
    }, 
}; 

代码可以递归走这哈希:

sub analyse_contig_tree_recursively { 
    my $TAXA_TREE = shift @_; 
    my $contig_hash = shift @_; 
    foreach (keys %{$TAXA_TREE}) { 
     print "$_ \n"; 
     analyse_contig_tree_recursively($TAXA_LEVEL->{$_}, $contig_hash); 
    } 
} 

回答

11

我不知道你打电话什么的analyse_contig_tree_recursively(你不使用$contig_hash参数的任何地方,而你还没有定义$TAXA_LEVEL:你的意思是$TAXA_TREE?),但是你的数据结构布局和你的递归遍历模式显然不匹配。您的遍历函数假定所有条目都是散列,并将空散列视为终止情况:如果keys %{$TAXA_TREE}为空,则不存在递归调用。给定你的数据,你需要测试一个值是否是一个散列值,如果你发现它不是散列值,那么就不会递归。

sub analyse_contig_tree_recursively { 
    my $TAXA_TREE   = shift @_; 
    foreach (keys %{$TAXA_TREE}){ 
     print "$_ \n"; 
     if (ref $TAXA_TREE->{$_} eq 'HASH') { 
      analyse_contig_tree_recursively($TAXA_TREE->{$_}); 
     } 
    } 
} 
+4

或'Scalar :: Util :: reftype($ TAXA_TREE - > {$ _})eq'HASH'',如果数据结构可能包含有福的对象。 – mob 2011-06-03 18:01:18

+0

@Giles:谢谢你。它暗示我的散列中有键,它不指向散列引用,并可能表示递归结束。关于$ TAXA_LEVEL,$ contig_hash:这些仅仅是我用于处理的其他一些变量。主要问题是现在清楚,我的程序工作...你们很快,真棒..谢谢一堆 – Abhi 2011-06-03 18:29:15

+0

男人,你们很快。如果你只是想看到你的结构,而不一定对它做任何事情,请使用[Data :: Dumper](http://perldoc.perl.org/Data/Dumper.html)。顺便说一句,当你进入哈希或哈希列表或哈希列表等列表时,是时候开始思考面向对象编程了。再花几分钟时间进行设置,但可以为您节省很多调试后的烦恼。我甚至推荐一次交易。 – 2011-06-03 20:06:29