Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
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 studying the Monastery: (5)
As of 2024-04-24 00:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found