Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Perl - Hashes

by Perlseeker_1 (Acolyte)
on Oct 13, 2013 at 12:26 UTC ( #1058070=perlquestion: print w/ replies, xml ) Need Help??
Perlseeker_1 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Experts,

I am learner in perl, i have question here please help me out

i have some files which contains data like below:

input

file 1 STD Area Name Amount 2 1 AB 1.0 2 2 AB-1 2.0 4 1 AB-4 1.0 4 2 AB-6 2.0
file 2 STD Area Name Amount 21 01 AB 4.0 22 12 AB-1 6.0 41 44 AB-4 9.0 42 46 AB-6 4.0 42 46 AB-6 4.0
file 3 STD Area Name Amount 01 10 AB 4.0 20 02 AB-1 6.0 40 04 AB-4 9.0 02 26 AB-6 4.0
file 4 STD Area Name Amount 56 01 AB 4.0 56 12 AB-1 6.0 65 44 AB-4 9.0 65 46 AB-6 4.0
Output: file 1 file 2 file 3 file 4 AB 1.0 4.0 4.0 4.0 AB-1 2.0 6.0 6.0 6.0 AB-4 1.0 9.0 9.0 9.0 AB-6 2.0 8.0 4.0 4.0

Each file contains common name where i need to add the Amount. can you please let me know how can i do this.

i tired as mentioned below:

my %result; my %hash = ( '2.1','AB', '2.2','AB-1', '4.1','AB-4', '4.2','AB-6', '21.01','AB', '22.12','AB-1', '41.44','AB-4', '42.46','AB-6', '42.46','AB-6', '01.10','AB', '20.02','AB-1', '40.04','AB-4', '02.26','AB-6', '56.01','AB', '56.12','AB-1', '65.44','AB-4', '65.46','AB-6'); foreach my $file (@files) { open FILE, "<$dir/$file" or warn "Couldn't open file ($!) or file ($!) + not found\n"; while (chomp ( my @fields = split /\t/, <FILE>) ) { my $key = "$fields[0].$fields[1]"; if (exists $hash{$key}) { $key = $hash{$key}; if (exists($result{$key})) { $result{$key} += $fields[03]; } else { $result{$key} += $fields[03]; } } } } close FILE;

Comment on Perl - Hashes
Select or Download Code
Re: Perl - Hashes
by tangent (Deacon) on Oct 13, 2013 at 14:05 UTC
    You are getting there, but the way you were reading, chomping and splitting all at once caused a few problems, safer to break it up. Also, you weren't closing each file within the loop. Try this:
    for my $file (@files) { my $ok = open (my $fh, "<", "$dir/$file.txt"); if (not $ok) { warn "Couldn't open file '$dir/$file.txt' ($!)\n"; next; } while (my $line = <$fh> ) { chomp $line; my @fields = split("\t",$line); my $key = $hash{"$fields[0].$fields[1]"} or next; $result{$key}{$file} += $fields[3]; } close $fh; } my $hline = join("\t",@files); print qq|\t$hline\n|; for my $key ( sort keys %result ) { my $amt = $result{$key}; my @cols = map { $amt->{$_} ? sprintf("%.1f",$amt->{$_}) : 'n/a' } + @files; my $line = join("\t",@cols); print qq|$key\t$line\n|; }
    Output:
    file_1 file_2 file_3 file_4 AB 1.0 4.0 4.0 4.0 AB-1 2.0 6.0 6.0 6.0 AB-4 1.0 9.0 9.0 9.0 AB-6 2.0 8.0 4.0 4.0
      Hi Experts,

      Thanks for the quick reply

      I need help on perl hashes.i have used hashes to store the data. i have fetched data from four files and stored data in hashes.

      key and value pair, code written to fetch data and store in hashes

      I have created four sub routines for file 1,file 2, file 3 and file 4, the key which i formed for each file will vary

      for file 1 --> $key = f[0].f1,file 2 --> f1.f2,file 3 --> $key = f4.f6,file 4 --> $key = f3.f4

      code for file 1

      my (%r1,%r2,%r3,%r4); my $Total; foreach my $file (@files) { open FILE, "<$dir/$file" or warn "Couldn't open file ($!) or file ($!) + not found\n"; while (chomp ( my @fields = split /\t/, <FILE>) ) { my $key = "$f[0].$f[1]"; if ($c{$key}) { $key = $c{$key}; if (exists($r1{$key})){ $r1{$key} += $f[02]; } else { $r1{$key} += $f[02]; } $Total +=$r1{$key}; } } $r1{'Total'} = $Total; } close FILE;

      Example input file 1

      A B 12.00 C D 13.00 E F 11.00 G H 22.00

      code for file 2

      foreach my $file (@files) { open FILE, "<$dir/$file" or warn "Couldn't open file ($!) or file ($!) + not found\n"; while (chomp ( my @fields = split /\t/, <FILE>) ) { my $key = "$f[1].$f[2]"; $key{'Output - Final'}=1; if ($c{$key}) { $key = $c{$key}; if (exists($r1{$key})){ $r1{$key} += $f[03]; } else { $r1{$key} += $f[03]; } $Total +=$r1{$key}; } } $r1{'Total'} = $Total; } close FILE;

      Example input file 2

      1 A B 12.00 2 C D 13.00 3 E F 11.00 4 G H 22.00

      Output got

      r1 --> hash contains data as ... Key Value Name F1.A AB 12.00 CD 13.00 EF 11.00 GH 22.00 r2 --> hash contains data as ... Key Value Name F2.B AB 01.00 CD 04.00 EF 42.00 GH 34.00 r3 --> hash contains data as ... Key Value Name F3.C AB 02.00 CD 03.00 EF 15.00 GH 20.00 r4 --> hash contains data as ... Key Value Name F4.D AB 62.00 CD 43.00 EF 24.00 GH 26.00

      Output expected

      Output - Final Name F1.A F2.B F3.C F4.D AB 12.00 01.00 02.00 62.00 CD 13.00 04.00 03.00 43.00 EF 11.00 42.00 15.00 24.00 GH 22.00 34.00 20.00 26.00 Total 58.00 81.00 40.00 155.00

      Thanks

        Hello Perlseeker_1
        How about using dispatch table? Sometimes I see monks use it.

        use strict; use warnings; use Data::Dumper; sub kv1{ my @flds=split(/\s+/, $_[0]); return( $flds[2], $flds[3] ); } sub kv2{ my @flds=split(/\s+/, $_[0]); return( $flds[1] . $flds[2], $flds[3] ); } my ($line,$fname, %data,%all, %kv_func); %kv_func=( #dispatch table 'file 1' => \&kv1, 'file 2' => \&kv1, 'file 3' => \&kv1, 'file 4' => \&kv1, 'file 5' => \&kv2, ); while( <DATA> ){ if (my $num = /^file/ .. /^\n/ ){ # test them with flip-flop chomp($line=$_); if( /^(file\s*\d+)/ ){ #begin of block $fname = $1; }elsif ($num =~ /E0/ ){ #end of block $all{$fname}={%data}; %data=(); } else { ##data lines my ($k,$v) = $kv_func{$fname}->($line); $data{$k}= exists($data{$k}) ? $data{$k}+$v : $v; } } } print Dumper \%all; __DATA__ file 1 2 1 AB 1.0 2 2 AB-1 2.0 4 1 AB-4 1.0 4 2 AB-6 2.0 a never comes here... file 2 21 01 AB 4.0 22 12 AB-1 6.0 41 44 AB-4 9.0 42 46 AB-6 4.0 42 46 AB-6 4.0 file 3 01 10 AB 4.0 20 02 AB-1 6.0 40 04 AB-4 9.0 02 26 AB-6 4.0 file 4 56 01 AB 4.0 56 12 AB-1 6.0 65 44 AB-4 9.0 65 46 AB-6 4.0 file 5 1 A B 12.00 2 C D 13.00 3 E F 11.00 4 G H 22.00

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (7)
As of 2014-09-30 23:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (386 votes), past polls