【问题标题】:How do I recursively walk a nested hash data structure?如何递归遍历嵌套哈希数据结构?
【发布时间】:2011-09-08 00:13:09
【问题描述】:

我被一个看似简单的概念问题困扰着。在 Web 和 Stack Overflow 上苦苦寻找类似的问题后,我找不到类似的东西,所以我想我可以问你。

我正在构建一个深度嵌套的 hash of hash 数据结构。深度可以为10-20次。为了这个问题,我只列出深度一。

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

它给了我以下错误:

在使用“strict refs”时,不能使用字符串(“1”)作为 HASH ref

很清楚:我的哈希必然有某些值为 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);
    }
}

【问题讨论】:

    标签: perl recursion hash


    【解决方案1】:

    我不确定你在调用什么 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->{$_});
            }
        }
    }
    

    【讨论】:

    • Scalar::Util::reftype($TAXA_TREE->{$_}) eq 'HASH',如果数据结构可能包含祝福对象。
    • @Giles:非常感谢。对我来说,我的哈希中有一些键不指向哈希引用并且可能表示递归结束。关于 $TAXA_LEVEL、$contig_hash:这些只是我用于处理的其他一些变量。主要问题现在很清楚了,我的程序可以正常工作了……你们又快又棒……非常感谢
    • 伙计,你们速度很快。如果您只是想查看您的结构而不一定要对它做任何事情,请使用Data::Dumper。顺便说一句,当您进入散列的散列或散列列表,或列表的散列列表等时,是时候开始考虑面向对象编程了。设置需要几分钟,但可以为您省去很多以后调试的心痛。即使是一次性交易,我也推荐它。
    • @David:感谢您的意见。你在谈论 Perl OOPs 吗?如果是这样,我很乐意看到一个例子。我不知道如何在 perl 中使用 OOP 来做同样的事情。我应该承认,除了 Moose 之外,我在 perl 中并没有使用很多 OOP,这很容易。
    • 是的,Perl OOP。我会修改结构。使这个类称为“family” 每个family包含两个成员:COUNT和MEMBERS,这是一个包含“family”对象的散列。成员函数将列出所有成员。然后,您可以递归调用此成员函数。当 Giles 发布答案时,我正在努力解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 2019-12-08
    • 1970-01-01
    • 2022-06-21
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 2013-07-14
    • 1970-01-01
    相关资源
    最近更新 更多