Patrick Andrieu: In komplexer Datenstruktur suchen

Beitrag lesen

Hallo alle!

Nehmen wir das Beispiel aus perldoc perldsc (ist auch in »Programmieren mit Perl« vorhanden):

 %TV = (  
     flintstones => {  
         series   => "flintstones",  
         nights   => [ "monday", "thursday", "friday" ],  
         members  => [  
             { name => "fred",    role => "husband", age  => 36, },  
             { name => "wilma",   role => "wife",    age  => 31, },  
             { name => "pebbles", role => "kid",     age  =>  4, },  
         ],  
     },  
  
     jetsons     => {  
         series   => "jetsons",  
         nights   => [ "wednesday", "saturday" ],  
         members  => [  
             { name => "george",  role => "husband", age  => 41, },  
             { name => "jane",    role => "wife",    age  => 39, },  
             { name => "elroy",   role => "kid",     age  =>  9, },  
         ],  
      },  
  
     simpsons    => {  
         series   => "simpsons",  
         nights   => [ "monday" ],  
         members  => [  
             { name => "homer", role => "husband", age => 34, },  
             { name => "marge", role => "wife",    age => 37, },  
             { name => "bart",  role => "kid",     age => [700, 800, 900], },  
         ],  
      },  
  
            others => ['south park', 'sponge bob', 'jimmy newtron'],  
  
            blubb => 'meerjungfraumann',  
   );

^^hier erweitert um zwei weiteren Schlüssel 'others' (Array) und 'blubb' (String)

Und jetzt nehmen wir an, ich habe eine Variable $someone = 'bart';. Habe ich eine Möglichkeit, herauszufinden, ob $someone in der Struktur vorhanden ist, und vor allem wo. Beispiel einer gewünschte Ausgabe wäre: $someone is known as a member of family simpsons and is their son. Also sozusagen der Weg rückwärts. Ich habe einen Wert, und will wissen, welche die enthaltende Struktur ist:

'bart' ist der Wert des Schlüssels 'name' des anonymen Hashs, der den Index 2 im anonymen Array hat, welcher der Wert vom Schlüssel 'members' des anonymen Hashs ist, der wiederum den Wert vom Schlüssel 'simpsons' des Hashs %TV darstellt - uff... ;)

Das folgende führt zwar einigermaßen zum Ziel, gibt es aber etwas Eleganteres?

my $somewhat = '900';  
  
searchfordata(\%TV, $somewhat);  
  
sub searchfordata {  
  my $wheretosearch = shift;  
  my $somewhat = shift;  
  my %wheretosearch = %$wheretosearch;  
  for (keys %wheretosearch) {  
    if (ref $wheretosearch{$_} eq 'ARRAY') {  
      $anarr = $wheretosearch{$_};  
      foreach (@{$wheretosearch{$_}}) {  
        print "$somewhat ist im $anarr\n" if $_ eq $somewhat;                                            # Oder ein Wert in einem Namensarray  
        if (ref $_ eq 'ARRAY') {  
          foreach (@{$wheretosearch{$_}}) {  
            print "$somewhat ist im $anarr\n" if $_ eq $somewhat;  
          }  
        }  
        elsif (ref $_ eq 'HASH') {  
           $anhash = $_;  
           searchfordata($anhash, $somewhat);  
        }  
      }  
    }  
    else {  
       print "$somewhat ist ein Schlüssel von $wheretosearch{$_}\n" if $_ eq $somewhat;                   # Vielleicht ist $somewhat einfach ein Schlüssel  
       print "$somewhat ist ein der Wert von $_ in %wheretosearch\n" if $wheretosearch{$_} eq $somewhat;  # könnte ja auch ein Wert sein  
       searchfordata($wheretosearch{$_}, $somewhat);  
    }  
  }  
}

900 ist im ARRAY(0x1831c04)

Bei $somewhat = 'simpsons' :
simpsons ist ein Schlüssel von HASH(0x1831cb8)
simpsons ist ein der Wert von series in %wheretosearch

Viele Grüße aus Frankfurt/Main,
Patrick

--

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