Как мне рекурсивно пройтись по структуре вложенных хеш-данных? - PullRequest
6 голосов
/ 03 июня 2011

Я застрял в том, что мне кажется простым концептуальным вопросом. После тщательного поиска похожих проблем в Интернете и переполнения стека я не смог найти что-то похожее, поэтому подумал, что могу спросить вас.

Я создаю хэш хэш структуры данных, которая глубоко вложена. Глубина может быть 10-20 раз. Ради этого вопроса я перечисляю только до глубины 1.

Я не могу рекурсивно пройтись по хеш-образцу ниже в Perl. Я также включил свой код.

Это дает мне следующую ошибку:

Невозможно использовать строку ("1") в качестве ссылки HASH, в то время как "строгие ссылки" используются в

Точно так же ясно: у моего хэша обязательно должны быть определенные ключи со значением 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);
    }
}

1 Ответ

12 голосов
/ 03 июня 2011

Я не уверен, что вы вызываете 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->{$_});
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...