Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

print out the values from a hash

by gibsonca (Beadle)
on Jan 11, 2013 at 17:33 UTC ( #1012932=perlquestion: print w/ replies, xml ) Need Help??
gibsonca has asked for the wisdom of the Perl Monks concerning the following question:

I am still struggling a bit with hashes. I want to count the number of strings of the form, "FREQ <val>" in a set of files. I can see that in fact I did count the strings, just not sure how to print the results.

use strict; use warnings; use Env; use integer; use Data::Dumper; my( %cnt, $file, @files, $key, $line, ); @files = <*.abc>; foreach $file (@files) { open (FILE, "$file"); my @contents=<FILE>; close FILE; my @freqs = grep(/ FREQ /,@contents); foreach $line (@freqs) { $line =~ s/ is begin.*//; $line =~ s/.* FREQ/FREQ/; #print "$file $line"; chomp($line); # start counting if (defined $cnt{$line}) { $cnt{$line}{c} = $cnt{$line}{c} + 1; } else { $cnt{$line}{c} = 1; $cnt{$line}{val} = $line; $cnt{$line}{file} = $file; } } # Print out results per file, all the found FREQs: # ( Definitely where I get it wrong starts here ) for $key ( keys %($cnt->{file}) ) { print "key $key \n"; } }

The intended results should be something like the following:

file1.abc FREQ 12.3 5 file1.abc FREQ 5 2 file2.abc FREQ 33.3 12

Comment on print out the values from a hash
Select or Download Code
Re: print out the values from a hash
by choroba (Canon) on Jan 11, 2013 at 17:52 UTC
    This is how I would do it. The main changes were:
    • Do not declare variables in a wider scope than needed.
    • Use lexical filehandles and 3-argument open with or die.
    • If you want to output frequencies per file, you have to store them per file. That's why the first key is the filename.
    • The line is already in the key, no need to store it again to a value.
    • You do not have to initialize the counting hash. Just increment it.
    #!/usr/bin/perl use warnings; use strict; my %cnt; for my $file (glob '*.abc') { open my $FILE, '<', "$file" or die "$!"; for my $line (grep / FREQ /, <$FILE>) { $line =~ s/ is begin.*//; $line =~ s/.* FREQ/FREQ/; chomp($line); $cnt{$file}{$line}++; } } for my $file ( keys %cnt) { for my $line ( keys %{ $cnt{$file} } ) { print "$file $line $cnt{$file}{$line}\n"; } }
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: print out the values from a hash
by Kenosis (Priest) on Jan 11, 2013 at 18:11 UTC

    choroba has provided excellent suggestions. Here an option that uses a hash of arrays (HoA), where the key is the file name and its associated value is a reference to a list of frequencies:

    use strict; use warnings; my %files; for my $file (<*.abc>) { open my $fh, '<', $file or die $!; while (<$fh>) { push @{ $files{$file} }, $1 if /FREQ\s+([\d.]+)/; } close $fh; } print "$_ FREQ @{ $files{$_} }\n" for keys %files;

    Output on files containing FREQ <val> info:

    file3.abc FREQ 27.047 400 file1.abc FREQ 33.3 2.22 file2.abc FREQ 12345.67

    Hope this helps!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1012932]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (19)
As of 2015-07-02 19:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (45 votes), past polls