2011-06-03 12 views
6

Sono bloccato con quello che sembra un semplice problema concettuale per me. Dopo aver cercato diligentemente problemi simili su Web e Stack Overflow, non sono riuscito a trovare qualcosa di simile, quindi ho pensato di poterlo chiedere.Come si cammina in modo ricorsivo una struttura di dati hash nidificata?

Sto costruendo un hash di hash struttura dati che è profondamente annidata. La profondità può essere di 10-20 volte. Per motivi di questo problema, sto elencando solo fino alla prima.

Non riesco a percorrere in modo ricorsivo l'hash di esempio di seguito in Perl. Ho anche incluso il mio codice.

Mi dà il seguente errore:

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

Basta quindi è chiaro: il mio hash è destinato ad avere alcune chiavi con valore 1. Non riesco a evitarli.

$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}, 
    }, 
}; 

Codice di camminare in modo ricorsivo questo hash:

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); 
    } 
} 

risposta

11

Non sono sicuro di quello che stai chiamando analyse_contig_tree_recursively su (non si sta usando che $contig_hash parametro da nessuna parte, e non è stata definita $TAXA_LEVEL: intendevi dire $TAXA_TREE?), Ma ovviamente c'è una discrepanza tra il layout della tua struttura dati e il tuo pattern di attraversamento ricorsivo. La tua funzione di attraversamento presuppone che tutte le voci siano hash e tratta gli hash vuoti come caso di terminazione: se keys %{$TAXA_TREE} è vuoto, non c'è una chiamata ricorsiva. Dati i tuoi dati, devi testare se un valore è un hash o no, e non recitare se trovi che non è un hash.

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

o 'Scalar :: Util :: reftype ($ TAXA_TREE -> {$ _}) eq 'HASH'', se la struttura dei dati potrebbe contenere oggetti benedetti. – mob

+0

@Giles: Grazie mille. A me sembra che ci siano delle chiavi nel mio hash che non puntano al riferimento all'hash e potrebbero segnalare la fine della ricorsione. Informazioni sul $ TAXA_LEVEL, $ contig_hash: quelle sono solo alcune delle altre variabili che uso per l'elaborazione. Il problema principale è chiaro ora e il mio programma funziona ... Voi ragazzi siete veloci e fantastici ... Grazie mille – Abhi

+0

Man, voi ragazzi siete veloci. Nel caso in cui desideri semplicemente vedere la tua struttura e non necessariamente fare qualcosa con essa, usa [Data :: Dumper] (http://perldoc.perl.org/Data/Dumper.html). A proposito, quando si entra in hash di hash o liste di hash, o liste di hash di liste, ecc., È il momento di iniziare a pensare alla programmazione orientata agli oggetti. Ci vogliono alcuni minuti in più per l'installazione, ma puoi risparmiare un sacco di problemi di debug in seguito. Lo consiglio anche per le offerte di un colpo. –

Problemi correlati