Patrick Andrieu: In komplexer Datenstruktur suchen

Beitrag lesen

Hallo Don P!

Ich habe den Eindruck, dass es ohne komplexere Funktion nicht geht, und eben da fehlt mir der Denkschubs ;)
Mal rein logisch betrachtet scheint es mir auch unmöglich, dass eine einfache und allgemeine rekursive Funktion das leisten kann, was du anscheinend vorhast.

Ja, wenn man sich die Funktionen im ersten von Siechfreds geposteten Link anschaut, sie spielen solange Ping Pong, bis alle Bälle aufgebraucht sind... :)

Mit einer einzigen Funktion ist mir die Rekursion auch nicht gelungen.

Da du anscheinend aber in Abhängigkeit von der Rekursionstiefe und womöglich auch sonstwie in Abhängigkeit von der Art der gefundenen Daten manchmal auch Geschwister und sogar deren Kinder ausgeben willst ("Other members are: 'homer' (husband, 34)..."), muss das zwangsläufig zu einem komplizierteren Algorithums führen, der dann wohl nicht mehr allgemein für jede solche Datenstruktur angewendet werden kann, mal ganz abgesehen von den grammatikalischen Schwierigkeiten, die dann für die Ausgabe entstehen ;-)

my %hash = # wie im OP  
  
my %pathdepths;  
my $somebody = 'marge';  
my $family = '';  
  
#### Funktionen aus dem geposteten Beitrag  
dump_data( 0, '$hash', \%hash );  
  
sub dump_data {  
    my ( $level, $base, $data ) = @_;  
    my $nextlevel = $level + 1;  
    if ( ref($data) eq 'ARRAY' ) {  
        foreach my $k ( 0 .. $#{$data} ) {  
            my $baseval = $base . '[' . $k . ']';  
            dump_it( $nextlevel, $baseval, $data->[$k] );  
        }  
    }  
    elsif ( ref($data) eq 'HASH' ) {  
        foreach my $k ( sort( keys( %{$data} ) ) ) {  
            my $baseval = $base . '{' . $k . '}';  
            dump_it( $nextlevel, $baseval, $data->{$k} );  
        }  
    }  
    elsif ( ref($data) eq 'SCALAR' ) {  
        my $baseval = $base;  
        dump_it( $nextlevel, $baseval, ${$data} );  
    }  
  
}  
  
sub dump_it {  
    my ( $nextlevel, $baseval, $datum ) = @_;  
    my $reftype = ref($datum);  
    if ( $reftype eq 'HASH' ) {  
        dump_data( $nextlevel, $baseval, \%{$datum} );  
    }  
    elsif ( $reftype eq 'ARRAY' ) {  
        dump_data( $nextlevel, $baseval, \@{$datum} );  
    }  
    else {  
        process_data( $nextlevel, $baseval, $datum );  
    }  
}  
  
sub process_data {  
    my ( $nextlevel, $baseval, $datum ) = @_;  
    $pathdepths{$baseval} = $datum;  # Hier wird %pathdepths gefüllt  
}  
# Ende Funktionsklau ;)  
  
for (sort keys %pathdepths) {  
  $family = $_ if $pathdepths{$_} eq $somebody;  
  $family =~ s/^\$hash\{(.+?)\}.*/$1/;  
}  
  
if (defined($hash{$family}{members})) {  
   foreach (@{$hash{$family}{members}}) {  
      print "$_->{name} ($_->{role}, $_->{age}) is member of '$family'. Other members are:", $/ if $_->{name} eq $somebody;  
  }  
   foreach (@{$hash{$family}{members}}) {  
      print "$_->{name} ($_->{role}, $_->{age})", $/ unless $_->{name} eq $somebody;  
  }  
}

^Z
marge (wife, 37) is member of 'simpsons'. Other members are:
homer (husband, 34)
bart (kid, ARRAY(0x1841380))

Das geht sicher sehr viel schöner - habe ich gestern auf die Schnelle gemacht - und setzt voraus, dass die Keys des »Oberhashs« tatsächlich den Familien entsprechen, also, dass man die Struktur schon soweit kennt. Aber mit einer Struktur, die man gar nicht kennt, dürfte es schwer sein zu arbeiten; zumindest den Aufbau sollte einigermaßen bekannt sein.

Viele Grüße aus Frankfurt/Main,
Patrick

--

_ - jenseits vom delirium - _
[link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
Nichts ist unmöglich? Doch!
Heute schon gegökt?