Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

One Hash Instead of Two

by Dru (Hermit)
on Feb 06, 2007 at 16:26 UTC ( [id://598574]=perlquestion: print w/replies, xml ) Need Help??

Dru has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I'm trying to build a complex hash (well, for me anyway) and I have succeeded for the most part. One thing that I am trying to do is count the number of times the source shows up in the file. It doesn't have to be tied to a specific entry, just a total number. I can do this by using two different hashes, but is it possible to do this with one hash?

Thanks,
Dru
my %count, %hash; while (<FILE>){ next unless /something/; if (/<LONG REGEX>/){ $hash{$3} = { sig => $1, src => $3, proto => $2, dst => $4, port => $5, }; if ($hash{$3}{src}){ $count{$3}++; } } }

Replies are listed 'Best First'.
Re: One Hash Instead of Two
by McDarren (Abbot) on Feb 06, 2007 at 16:39 UTC
    I suspect that this code is probably not really doing what you think it is. You are using $3 as a key to your hash on each iteration. Because hash keys must be unique, each time you find a "src" that you've had before, the previous one will simply be overwritten. I suspect this isn't really what you want.

    I could suggest an alternative approach, but first I'd like to see some sample data and the output you would expect to get.

    Cheers,
    Darren :)

Re: One Hash Instead of Two
by davorg (Chancellor) on Feb 06, 2007 at 16:30 UTC
Re: One Hash Instead of Two
by polettix (Vicar) on Feb 06, 2007 at 18:44 UTC
    If the count is all you need, you don't need of %hash at all:
    my %count; while (<FILE>){ next unless /something/; if (/<LONG REGEX>/){ $count{$3}++ if $3; } }

    If McDarren is correct, and you want to keep track of all items, you should probably maintain an array inside $hash{$3} (and a variable rename would be good in this case), and in this case you would have the count "for free", just looking at how many elements each item has:

    my %hashes_for; # More sensible name while (<FILE>){ next unless /something/; if (/<LONG REGEX>/){ push @{$hashes_for{$3}}, { sig => $1, src => $3, proto => $2, dst => $4, port => $5, }; } } # You can now use scalar(@{$hashes_for{whatever}}) instead of $count{w +hatever}

    Note: untested code!

    Flavio
    perl -ple'$_=reverse' <<<ti.xittelop@oivalf

    Don't fool yourself.
Re: One Hash Instead of Two
by Dru (Hermit) on Feb 06, 2007 at 21:25 UTC
    All,

    Thank you for your help. This is the code I decided to go with:
    my %hash; while (<FILE>){ next unless /Something/; if (/<LONG REGEX>/){ if ($hash{$3}){ $hash{$3}{count}++; next; } $hash{$3} = { sig => $1, src => $3, proto => $2, dst => $4, port => $5, }; } }
    davorg,

    I based my code on yours, just changed it a bit. Thanks for the tip on Data::Dumper, I've heard about it before, just never used it. Very cool

    McDarren,

    Believe it or not, one entry from each source is all I really need. I believe this code will speed things up a bit since it will count the source and go to the next one if we already have it.

    fenLisesi,

    Thanks, I tend to do that more then I wish to admit.

    frodo72,

    Thanks for the code and reply. If I need to build the more complex data structure, I'll probably do something similar to what you gave me. I'll just have to brush up on perlreftut first.

    -Dru
Re: One Hash Instead of Two
by fenLisesi (Priest) on Feb 06, 2007 at 18:32 UTC
    Side issue: you probably want my (%count, %hash);. Cheers.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://598574]
Approved by chargrill
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2024-04-25 18:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found