Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Hash of hashes w/ perls built in db 1

Status
Not open for further replies.

jrig

Technical User
Sep 5, 2006
36
US
Still learning the ins/outs of hashes...this code seems to work, but not when reading from the db (uncommenting db lines). I understand the database stores data as a hash so perhaps I am missing something?
Code:
#!/usr/bin/perl  -w
       
#dbmopen(%events,"events",0666)||die;
%events = (
    q123 => {
        husband   => "fred",
        wife      => "wilma",
    },
    q456 => {
        husband   => "george",
        wife      => "jane",
    },
    q789 => {
        husband   => "homer",
        wife      => "marge",
    },
);
for $family ( sort keys %events ) {
    print "$family: ";
    for $role ( keys %{ $events{$family} } ) {
    if($role =~ /husband/){ print "$role=$events{$family}{$role} ";}
}}
#dbmclose(%events);
exit;
 
Your code is good, it's just that DBM does not support complex data stuctures. You would need to use the MLDBM module to accomplish what you are trying to do.

Use the Storable and/or Data::Dumper modules for practicing with complex data structures. Both are core modules included with perl 5.8

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Thanks Kevin MLDBM did the trick, got my hashes working reasonably well. Still learning though. Couple questions. The actual data is in a db, but here's a sample to give an idea of the setup-
Code:
#!/usr/bin/perl  -w
 
my %events;
 
$events{ c111 } = {
    tags      => "english" ,
    desc      => "one two three",
    user      => "jrig"
    };
 
$events{ d222 } = {
    tags      => "spanish" ,
    desc      => "uno dos tres",
    user      => "newt"
    };
 
$events{ e333 } = {
    tags      => "german" ,
    desc      => "eine zwei drei",
    user      => "pita"
    };
       
@terms=('e' , 'r');
foreach $term (@terms){
       
for $eventnum ( keys %events ) {
    for $role ( keys %{ $events{$eventnum} } ) {
    if ($role eq 'tags'){
        if ($events{$eventnum}{$role} =~ /$term/){
                        push @match , $eventnum;}
                                        }
                                }
                        }
}#foreach
 
for ( @match ) {$i++;
        print "$i) $_: ";
        print $events{$_}{'tags'}."\n";
               }
The aim is to search through the sub(?) hash's tags and return matches, and then display the tags.
1) The first nested 'fors' seem kinda longwinded, should I try to optimize? I've seen some examples using 'while/each' but I don't see how to implement here, suggestions?
2) @matches may (does) contain dupes. Any way to prevent this within the loop, or is the @saw{@match} = ();@out = keys %saw; method the best bet here?
3)+MOST IMPORTANT+ How do I reference the hashes which have been displayed. Say for instance, I want to display the 'desc' value for the 2nd hash that was printed, How would I reference it? I'm thinking I can use the $i somehow, but it isnt clicking.

Ideas about any part would be greatly appreciated. TIA

Joe
 
one way to avoid duplication is use a hash. Make what ever you don't want duplicated a hash key:


Code:
[blue]@terms[/blue]=[red]([/red][red]'[/red][purple]e[/purple][red]'[/red] , [red]'[/red][purple]r[/purple][red]'[/red][red])[/red][red];[/red]
[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]%dups[/blue] = [red]([/red][red])[/red][red];[/red]
[olive][b]foreach[/b][/olive] [blue]$term[/blue] [red]([/red][blue]@terms[/blue][red])[/red][red]{[/red]
   [olive][b]for[/b][/olive] [blue]$eventnum[/blue] [red]([/red] [url=http://perldoc.perl.org/functions/keys.html][black][b]keys[/b][/black][/url] [blue]%events[/blue] [red])[/red] [red]{[/red]
      [olive][b]for[/b][/olive] [blue]$role[/blue] [red]([/red] [black][b]keys[/b][/black] [blue]%[/blue][red]{[/red] [blue]$events[/blue][red]{[/red][blue]$eventnum[/blue][red]}[/red] [red]}[/red] [red])[/red] [red]{[/red]
         [olive][b]if[/b][/olive] [red]([/red][blue]$role[/blue] eq [red]'[/red][purple]tags[/purple][red]'[/red][red])[/red][red]{[/red]
            [olive][b]if[/b][/olive] [red]([/red][blue]$events[/blue][red]{[/red][blue]$eventnum[/blue][red]}[/red][red]{[/red][blue]$role[/blue][red]}[/red] =~ [red]/[/red][purple][blue]$term[/blue][/purple][red]/[/red][red])[/red][red]{[/red]
               [olive][b]unless[/b][/olive] [red]([/red][url=http://perldoc.perl.org/functions/exists.html][black][b]exists[/b][/black][/url] [blue]$dups[/blue][red]{[/red][blue]$eventnum[/blue][red]}[/red][red])[/red] [red]{[/red] 
                  [url=http://perldoc.perl.org/functions/push.html][black][b]push[/b][/black][/url] [blue]@match[/blue] , [blue]$eventnum[/blue][red];[/red]
                  [blue]$dups[/blue][red]{[/red][blue]$eventnum[/blue][red]}[/red]=[fuchsia]1[/fuchsia][red];[/red]
               [red]}[/red]     
            [red]}[/red]
         [red]}[/red]
      [red]}[/red]
   [red]}[/red]
[red]}[/red]
 
[olive][b]for[/b][/olive] [red]([/red] [blue]@match[/blue] [red])[/red] [red]{[/red]
        [blue]$i[/blue]++[red];[/red]
        [url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] [red]"[/red][purple][blue]$i[/blue]) [blue]$_[/blue]: [/purple][red]"[/red][red];[/red]
        [black][b]print[/b][/black] [blue]$events[/blue][red]{[/red][blue]$_[/blue][red]}[/red][red]{[/red][red]'[/red][purple]tags[/purple][red]'[/red][red]}[/red].[red]"[/red][purple][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
[red]}[/red]

3)+MOST IMPORTANT+ How do I reference the hashes which have been displayed. Say for instance, I want to display the 'desc' value for the 2nd hash that was printed, How would I reference it? I'm thinking I can use the $i somehow, but it isnt clicking.

seems like you already figured that out:

Code:
for ( @match ) {$i++;
        print "$i) $_: ";
        [b]print $events{$_}{'tags'}."\n";[/b]
}

just use {'desc'} like you have {'tags'} in the above block.



------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Thanks Kevin, sound advice as per usual. I think I was unclear about #3. What I meant is: the script above has run, it displays ~
Code:
1) c111: english
2) e333: german
now I'm staring at blinking cursor. I want to be able to hit '1' and display the description ('desc') for the event hash that has the '1' in front of it. Perhaps I'm over thinking it, but it seems like I need to build some sort of pointer in the 'for @match' loop so I can back-reference the hashes displayed. Does that make any sense, or have I just lost it?
 
makes sense:

Code:
[gray]#!perl[/gray]
[url=http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/url] [green]strict[/green][red];[/red]
[black][b]use[/b][/black] [green]warnings[/green][red];[/red]
 
[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]%events[/blue][red];[/red]
 
[blue]$events[/blue][red]{[/red] [purple]c111[/purple] [red]}[/red] = [red]{[/red]
    [purple]tags[/purple]      => [red]"[/red][purple]english[/purple][red]"[/red] ,
    [purple]desc[/purple]      => [red]"[/red][purple]one two three[/purple][red]"[/red],
    [purple]user[/purple]      => [red]"[/red][purple]jrig[/purple][red]"[/red]
    [red]}[/red][red];[/red]
 
[blue]$events[/blue][red]{[/red] [purple]d222[/purple] [red]}[/red] = [red]{[/red]
    [purple]tags[/purple]      => [red]"[/red][purple]spanish[/purple][red]"[/red] ,
    [purple]desc[/purple]      => [red]"[/red][purple]uno dos tres[/purple][red]"[/red],
    [purple]user[/purple]      => [red]"[/red][purple]newt[/purple][red]"[/red]
    [red]}[/red][red];[/red]
 
[blue]$events[/blue][red]{[/red] [purple]e333[/purple] [red]}[/red] = [red]{[/red]
    [purple]tags[/purple]      => [red]"[/red][purple]german[/purple][red]"[/red] ,
    [purple]desc[/purple]      => [red]"[/red][purple]eine zwei drei[/purple][red]"[/red],
    [purple]user[/purple]      => [red]"[/red][purple]pita[/purple][red]"[/red]
    [red]}[/red][red];[/red]
       
[black][b]my[/b][/black] [blue]@terms[/blue]=[red]([/red][red]'[/red][purple]e[/purple][red]'[/red] , [red]'[/red][purple]r[/purple][red]'[/red][red])[/red][red];[/red]
[black][b]my[/b][/black] [blue]%dups[/blue] = [red]([/red][red])[/red][red];[/red]
[black][b]my[/b][/black] [blue]@match[/blue][red];[/red]
[olive][b]foreach[/b][/olive] [black][b]my[/b][/black] [blue]$term[/blue] [red]([/red][blue]@terms[/blue][red])[/red][red]{[/red]
   [olive][b]foreach[/b][/olive] [black][b]my[/b][/black] [blue]$eventnum[/blue] [red]([/red] [url=http://perldoc.perl.org/functions/keys.html][black][b]keys[/b][/black][/url] [blue]%events[/blue] [red])[/red] [red]{[/red]
      [olive][b]if[/b][/olive] [red]([/red][blue]$events[/blue][red]{[/red][blue]$eventnum[/blue][red]}[/red][red]{[/red]tags[red]}[/red] =~ [red]/[/red][purple][blue]$term[/blue][/purple][red]/[/red][red])[/red][red]{[/red]
         [olive][b]unless[/b][/olive] [red]([/red][url=http://perldoc.perl.org/functions/exists.html][black][b]exists[/b][/black][/url] [blue]$dups[/blue][red]{[/red][blue]$eventnum[/blue][red]}[/red][red])[/red] [red]{[/red]
            [url=http://perldoc.perl.org/functions/push.html][black][b]push[/b][/black][/url] [blue]@match[/blue] , [blue]$eventnum[/blue][red];[/red]
               [blue]$dups[/blue][red]{[/red][blue]$eventnum[/blue][red]}[/red]=[fuchsia]1[/fuchsia][red];[/red]
         [red]}[/red]
      [red]}[/red]
   [red]}[/red]
[red]}[/red]
[black][b]my[/b][/black] [blue]$i[/blue] = [fuchsia]0[/fuchsia][red];[/red] 
[olive][b]for[/b][/olive] [red]([/red] [blue]@match[/blue] [red])[/red] [red]{[/red]
   [url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] ++[blue]$i[/blue], [red]"[/red][purple]) [blue]$_[/blue]: [blue]$events[/blue]{[blue]$_[/blue]}{'tags'}[purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
[red]}[/red]
[black][b]print[/b][/black] [red]"[/red][purple]Enter a number to see the details: [/purple][red]"[/red][red];[/red]
[url=http://perldoc.perl.org/functions/chomp.html][black][b]chomp[/b][/black][/url][red]([/red][black][b]my[/b][/black] [blue]$n[/blue] = <STDIN>[red])[/red][red];[/red]
[olive][b]foreach[/b][/olive] [black][b]my[/b][/black] [blue]$key[/blue] [red]([/red] [black][b]keys[/b][/black] [blue]%[/blue][red]{[/red] [blue]$events[/blue][red]{[/red][blue]$match[/blue][red][[/red][blue]$n[/blue]-[fuchsia]1[/fuchsia][red]][/red][red]}[/red] [red]}[/red] [red])[/red] [red]{[/red]
   [black][b]print[/b][/black] [red]"[/red][purple][blue]$key[/blue] =  [blue]$events[/blue]{[blue]$match[/blue][[blue]$n[/blue]-1]}{[blue]$key[/blue]}[purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
[red]}[/red]
[tt]------------------------------------------------------------
Pragmas (perl 5.8.8) used :
[ul]
[li]strict - Perl pragma to restrict unsafe constructs[/li]
[li]warnings - Perl pragma to control optional warnings[/li]
[/ul]
[/tt]

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top