Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Perl - write data from hashes

by Perlseeker_1 (Acolyte)
on Oct 13, 2013 at 14:38 UTC ( #1058077=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 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

Comment on Perl - write data from hashes
Select or Download Code
Re: Perl - write data from hashes
by aitap (Deacon) on Oct 13, 2013 at 15:24 UTC

    Are the keys in all the hashes always the same? If yes, here's an algorythm for you:

    1. Get the list of keys from any of the hashes, possibly sort it or make the Name key first somehow
    2. For each of the keys you got, print its name, then (joined by "\t" between them) its values from your collected hashes
    3. You'll probably want to use an array of hashes (read perlreftut and perldsc for more info) instead of just a bunch of numbered variables.
    Example code using an array of hashes (untested):
    for my $key ("Name", grep { $_ ne "Name" } keys %{$hashes[0]}) { print ((join "\t", $key, map { $_->{$key} } @hashes),"\n"); }
    It could have been easier to print Name first it you didn't mix it with the other data.

    Edit: forgot to print "\n"

      joined by "\t" between

      in case that turns out less then perfect, resort to printf or sprintf

      Cheers, Sören

      Créateur des bugs mobiles - let loose once, run everywhere.
      (hooked on the Perl Programming language)

Re: Perl - write data from hashes
by CountZero (Bishop) on Oct 13, 2013 at 17:25 UTC
    This part of your code is rather strange:
    if (exists($r1{$key})){ $r1{$key} += $f[02]; } else { $r1{$key} += $f[02]; }
    You do exactly the same whether or not the key already exists in the hash. Therefore you can replace this simply by:
    $r1{$key} += $f[02];

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
      Interesting.

      In older versions of Perl, I encountered the issue where attempting to add a value to an undefined hash element would generate a warning.

      I see under my modern version of Perl, this is not an issue:

      #!/usr/bin/perl -w use strict; my $TEST_KEY = 'abc'; my $TEST_VAL = 5; my %TestHash = (); { print "-----[ Addition to undef ]---------------\n"; %TestHash = (); $TestHash{$TEST_KEY} += $TEST_VAL; print "-----[ Addition testing for undef ]------\n"; %TestHash = (); if (defined $TestHash{$TEST_KEY}) { $TestHash{$TEST_KEY} += $TEST_VAL; } else { $TestHash{$TEST_KEY} = $TEST_VAL; } } exit; __END__ C:\Steve\Dev\PerlMonks\P-2013-10-13@2339-HashUndef>hashtest.pl -----[ Addition to undef ]--------------- -----[ Addition testing for undef ]------

      I think -- not 100% sure, but I think -- I am happy about this.

Re: Perl - write data from hashes
by Lennotoecom (Pilgrim) on Oct 13, 2013 at 20:19 UTC
    Mr. aitap I tested your snippet, without modification it would give away
    "Modification of a read-only value attempted at" error
    nevertheless that snippet of yours is a beautiful code mate
    and here i'm using it
    thank you
    and here the complete script for the author, it processes 4 files in a loop
    files are named file1-4
    for ($i = 1; $i < 5; $i++){ $a[$i]{'name'} = "file$i"; open IN, "<file$i" or die $!; while(<IN>){ if (/(\w)\t(\w)\t([\d\.]+)/){ $a[$i]{"$1$2"} = $3; $a[$i]{'total'} = sprintf('%.2f', $a[$i]{'total'}+=$3) +; } } close(IN); } foreach $key ('name', grep {$_ ne 'name'} sort keys $a[1]){ print join "\t", $key, map($_->{$key}, @a[1..4]),"\n"; }
    and output:
    name file1 file2 file3 file4 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
    files which are used, created from the author's output:
    ~@deb:~/perl/9# cat file1 A B 12.00 C D 13.00 E F 11.00 G H 22.00 ~@deb:~/perl/9# cat file2 1 A B 01.00 2 C D 04.00 3 E F 42.00 4 G H 34.00 ~@deb:~/perl/9# cat file3 A B 02.00 C D 03.00 E F 15.00 G H 20.00 ~@deb:~/perl/9# cat file4 1 A B 62.00 2 C D 43.00 3 E F 24.00 4 G H 26.00

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (8)
As of 2014-09-18 19:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

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











    Results (121 votes), past polls