Properly displaying items from hash

Properly displaying items from hash

am 24.04.2008 03:35:29 von rsarpi

I have two files: log_ca.txt and log_aa.txt
contents of log_ca.txt:

333333333->ca_filename3
444444444->ca_filename4
111111111->ca_filename1
222222222->ca_filename2

contents of log_aa.txt:

111111111->aa_filename1
333333333->aa_filename3
222222222->aa_filename2
444444444->aa_filename4

The program extracts the values after the -> delimiter of both files
Makes an association between the values on both of the files.

Meaning, this is desired output:

CA FILENAME => AA_FILENAME
---------------------------
ca_filename1 => aa_filename1
ca_filename2 => aa_filename2
ca_filename3 => aa_filename3
ca_filename4 => aa_filename4


Outputs I'm getting
(see "double pop" in code below for details)

CA FILENAME => AA_FILENAME
---------------------------
=>
ca_filename3 => aa_filename3
ca_filename4 => aa_filename4

and

(after adding the "double pop" below prints all records but still get
the => delimiter)
CA FILENAME => AA_FILENAME
---------------------------
=>
ca_filename1 => aa_filename1
ca_filename2 => aa_filename2
ca_filename3 => aa_filename3
ca_filename4 => aa_filename4


Questions:
How do I get the desired output without resorting to the 'double pop'?
How do I get rid of the extra "=>"?

Thanks in advance.


#!/usr/bin/perl
use warnings;
use strict;

my $ca_path = "log_ca.txt";
my $aa_path = "log_aa.txt";


my %final_report;
my @ca_filenames;
my @aa_filenames;


open (CAFILE, $ca_path) or die $!;
my @ca_files = ;

open(AAFILE, $aa_path) or die $!;
my @aa_files = ;


#sort arrays
my @ca_files_sorted = sort @ca_files;
my @aa_files_sorted = sort @aa_files;

my $total_items = @ca_files_sorted;

foreach(@ca_files_sorted){
s/[\r\t\n]+//; #Remove carriage returns and new lines
my @temp = split (/\d+->/, $_);
push @ca_filenames, @temp;
}



foreach(@aa_files_sorted){
s/[\r\t\n]+//; #Remove carriage returns and new lines
my @temp = split (/\d+->/, $_);
push @aa_filenames, @temp;
}

###problems start here
#why do I need to put pop@... twice?
#otherwise it won't display all items.
#I don't put that this is the outcome.
#CA FILENAME => AA_FILENAME
# =>
#ca_filename3 => aa_filename3
#ca_filename4 => aa_filename4


for (1..$total_items){
$final_report{ pop @ca_filenames } = pop @aa_filenames;
$final_report{ pop @ca_filenames } = pop @aa_filenames;
}

#why do I get the '=>' symbol there?
print "CA FILENAME => AA_FILENAME\n";
foreach (sort { $a cmp $b } keys(%final_report) ){
print "$_ => $final_report{$_}\n";
}


--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: Properly displaying items from hash

am 24.04.2008 13:09:13 von peng.kyo

On Thu, Apr 24, 2008 at 9:35 AM, icarus wrote:
> I have two files: log_ca.txt and log_aa.txt
> contents of log_ca.txt:
>
> 333333333->ca_filename3
> 444444444->ca_filename4
> 111111111->ca_filename1
> 222222222->ca_filename2
>
> contents of log_aa.txt:
>
> 111111111->aa_filename1
> 333333333->aa_filename3
> 222222222->aa_filename2
> 444444444->aa_filename4
>
> The program extracts the values after the -> delimiter of both files
> Makes an association between the values on both of the files.
>
> Meaning, this is desired output:
>
> CA FILENAME => AA_FILENAME
> ---------------------------
> ca_filename1 => aa_filename1
> ca_filename2 => aa_filename2
> ca_filename3 => aa_filename3
> ca_filename4 => aa_filename4
>


It's may easy or not, based on the special cases you have.
I could show one of the ways:

use strict;
use warnings;

my (%hash, %hash2);

open my $hd, 'log_aa.txt' or die $!;
while(<$hd>) {
next if /^$/;
chomp;
my ($id) = /(\d+)$/;
my $f_name = (split/->/,$_)[-1];
$hash{$id} = $f_name;
}
close $hd;

open $hd, 'log_ca.txt' or die $!;
while(<$hd>) {
next if /^$/;
chomp;
my ($id) = /(\d+)$/;
my $f_name = (split/->/,$_)[-1];
$hash2{$id} = $f_name;
}
close $hd;

for (sort keys %hash) {
print $hash{$_}, "=>", $hash2{$_}, "\n";
}

__END__

Hope this helps.

--
J. Peng - QQMail Operation Team
eMail: peng.kyo@gmail.com AIM: JeffHua

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: Properly displaying items from hash

am 24.04.2008 13:51:16 von Gunnar Hjalmarsson

icarus wrote:
> I have two files: log_ca.txt and log_aa.txt
> contents of log_ca.txt:
>
> 333333333->ca_filename3
> 444444444->ca_filename4
> 111111111->ca_filename1
> 222222222->ca_filename2
>
> contents of log_aa.txt:
>
> 111111111->aa_filename1
> 333333333->aa_filename3
> 222222222->aa_filename2
> 444444444->aa_filename4
>
> The program extracts the values after the -> delimiter of both files
> Makes an association between the values on both of the files.
>
> Meaning, this is desired output:
>
> CA FILENAME => AA_FILENAME
> ---------------------------
> ca_filename1 => aa_filename1
> ca_filename2 => aa_filename2
> ca_filename3 => aa_filename3
> ca_filename4 => aa_filename4

Suggested code:

print "CA FILENAME => AA_FILENAME\n";
print '-' x 27, "\n";

open my $ca, '<', 'log_ca.txt' or die $!;
my %ca;
while ( <$ca> ) {
chomp;
my ($k, $v) = split /->/;
$ca{$k} = $v;
}

open my $aa, '<', 'log_aa.txt' or die $!;
foreach ( sort <$aa> ) {
chomp;
my ($k, $v) = split /->/;
print "$ca{$k} => $v\n";
}

> Outputs I'm getting
> (see "double pop" in code below for details)
>
> CA FILENAME => AA_FILENAME
> ---------------------------
> =>
> ca_filename3 => aa_filename3
> ca_filename4 => aa_filename4
>
> and
>
> (after adding the "double pop" below prints all records but still get
> the => delimiter)
> CA FILENAME => AA_FILENAME
> ---------------------------
> =>
> ca_filename1 => aa_filename1
> ca_filename2 => aa_filename2
> ca_filename3 => aa_filename3
> ca_filename4 => aa_filename4
>
>
> Questions:
> How do I get the desired output without resorting to the 'double pop'?

See suggested change below.

> How do I get rid of the extra "=>"?

That is also taken care of if you change those lines as suggested.



> foreach(@ca_files_sorted){
> s/[\r\t\n]+//; #Remove carriage returns and new lines
> my @temp = split (/\d+->/, $_);
> push @ca_filenames, @temp;

That does not do what you think it does. Check the contents of @temp to
see what I mean.

You probably want to replace the two latest lines with:

my ($temp) = /\d+->(.+)/;
push @ca_filenames, $temp;

> foreach(@aa_files_sorted){
> s/[\r\t\n]+//; #Remove carriage returns and new lines
> my @temp = split (/\d+->/, $_);
> push @aa_filenames, @temp;

Ditto.

> #why do I need to put pop@... twice?

Because @ca_filenames and @aa_filenames contain empty elements.

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: Properly displaying items from hash

am 24.04.2008 14:12:57 von krahnj

icarus wrote:
> I have two files: log_ca.txt and log_aa.txt
> contents of log_ca.txt:
>
> 333333333->ca_filename3
> 444444444->ca_filename4
> 111111111->ca_filename1
> 222222222->ca_filename2
>
> contents of log_aa.txt:
>
> 111111111->aa_filename1
> 333333333->aa_filename3
> 222222222->aa_filename2
> 444444444->aa_filename4
>
> The program extracts the values after the -> delimiter of both files
> Makes an association between the values on both of the files.
>
> Meaning, this is desired output:
>
> CA FILENAME => AA_FILENAME
> ---------------------------
> ca_filename1 => aa_filename1
> ca_filename2 => aa_filename2
> ca_filename3 => aa_filename3
> ca_filename4 => aa_filename4
>
>
> Outputs I'm getting
> (see "double pop" in code below for details)
>
> CA FILENAME => AA_FILENAME
> ---------------------------
> =>
> ca_filename3 => aa_filename3
> ca_filename4 => aa_filename4
>
> and
>
> (after adding the "double pop" below prints all records but still get
> the => delimiter)
> CA FILENAME => AA_FILENAME
> ---------------------------
> =>
> ca_filename1 => aa_filename1
> ca_filename2 => aa_filename2
> ca_filename3 => aa_filename3
> ca_filename4 => aa_filename4
>
>
> Questions:
> How do I get the desired output without resorting to the 'double pop'?
> How do I get rid of the extra "=>"?
>
> Thanks in advance.
>
>
> #!/usr/bin/perl
> use warnings;
> use strict;
>
> my $ca_path = "log_ca.txt";
> my $aa_path = "log_aa.txt";
>
>
> my %final_report;
> my @ca_filenames;
> my @aa_filenames;
>
>
> open (CAFILE, $ca_path) or die $!;
> my @ca_files = ;
>
> open(AAFILE, $aa_path) or die $!;
> my @aa_files = ;
>
>
> #sort arrays
> my @ca_files_sorted = sort @ca_files;
> my @aa_files_sorted = sort @aa_files;
>
> my $total_items = @ca_files_sorted;
>
> foreach(@ca_files_sorted){
> s/[\r\t\n]+//; #Remove carriage returns and new lines
> my @temp = split (/\d+->/, $_);

Assuming that $_ contains '111111111->ca_filename1' then @temp now
contains ( '', 'ca_filename1' ).


> push @ca_filenames, @temp;
> }

At the end of the loop @ca_filenames will contain:

( '', 'ca_filename1', '', 'ca_filename2', '', 'ca_filename3', '',
'ca_filename4' )


You need to store only the string after /\d+->/:

foreach ( @ca_files_sorted ) {
s/\s+\z//; # Remove all trailing whitespace
push @ca_filenames, /\d+->(.+)/;
}


> foreach(@aa_files_sorted){
> s/[\r\t\n]+//; #Remove carriage returns and new lines
> my @temp = split (/\d+->/, $_);
> push @aa_filenames, @temp;
> }

As above, at the end of the loop @aa_filenames will contain:

( '', 'aa_filename1', '', 'aa_filename2', '', 'aa_filename3', '',
'aa_filename4' )


> ###problems start here
> #why do I need to put pop@... twice?

Because @ca_filenames has twice as many elements as @ca_files_sorted
(where $total_items was derived from.)

> #otherwise it won't display all items.
> #I don't put that this is the outcome.
> #CA FILENAME => AA_FILENAME
> # =>
> #ca_filename3 => aa_filename3
> #ca_filename4 => aa_filename4
>
>
> for (1..$total_items){
> $final_report{ pop @ca_filenames } = pop @aa_filenames;
> $final_report{ pop @ca_filenames } = pop @aa_filenames;
> }

And so you end up with a hash that has a key '' and a corresponding
value ''.

You could accomplish the same thing more simply with a hash slice (no
loop required):

@final_report{ @ca_filenames } = @aa_filenames;


> #why do I get the '=>' symbol there?
> print "CA FILENAME => AA_FILENAME\n";
> foreach (sort { $a cmp $b } keys(%final_report) ){
> print "$_ => $final_report{$_}\n";
> }


John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: Properly displaying items from hash

am 24.04.2008 21:17:26 von rsarpi

Thanks everybody...here is the final code I crafted from my original
and your suggestions.

#!/usr/bin/perl
use warnings;
use strict;

my $ca_path = "log_ca.txt";
my $aa_path = "log_aa.txt";


my %final_report;
my @ca_filenames;
my @aa_filenames;


open (CAFILE, $ca_path) or die $!;
my @ca_files = ;

open(AAFILE, $aa_path) or die $!;
my @aa_files = ;


#sort arrays
my @ca_files_sorted = sort @ca_files;
my @aa_files_sorted = sort @aa_files;

my $total_items = @ca_files_sorted;

foreach(@ca_files_sorted){
s/\s+\z//; # Remove all trailing whitespace
push @ca_filenames, /\d+->(.+)/;
}



foreach(@aa_files_sorted){
s/\s+\z//; # Remove all trailing whitespace
push @aa_filenames, /\d+->(.+)/;
}

for (1..$total_items){
$final_report{ pop @ca_filenames } = pop @aa_filenames;
}



print "CA FILENAME => AA_FILENAME\n";
print '-' x 27, "\n";
foreach (sort { $a cmp $b } keys(%final_report) ){
print "$_ => $final_report{$_}\n";
}


Now it prints the output just fine.

Thanks again.


On Apr 24, 2:12 am, kra...@telus.net (John W. Krahn) wrote:
> icarus wrote:
> > I have two files: log_ca.txt and log_aa.txt
> > contents of log_ca.txt:
>
> > 333333333->ca_filename3
> > 444444444->ca_filename4
> > 111111111->ca_filename1
> > 222222222->ca_filename2
>
> > contents of log_aa.txt:
>
> > 111111111->aa_filename1
> > 333333333->aa_filename3
> > 222222222->aa_filename2
> > 444444444->aa_filename4
>
> > The program extracts the values after the -> delimiter of both files
> > Makes an association between the values on both of the files.
>
> > Meaning, this is desired output:
>
> > CA FILENAME => AA_FILENAME
> > ---------------------------
> > ca_filename1 => aa_filename1
> > ca_filename2 => aa_filename2
> > ca_filename3 => aa_filename3
> > ca_filename4 => aa_filename4
>
> > Outputs I'm getting
> > (see "double pop" in code below for details)
>
> > CA FILENAME => AA_FILENAME
> > ---------------------------
> > =>
> > ca_filename3 => aa_filename3
> > ca_filename4 => aa_filename4
>
> > and
>
> > (after adding the "double pop" below prints all records but still get
> > the => delimiter)
> > CA FILENAME => AA_FILENAME
> > ---------------------------
> > =>
> > ca_filename1 => aa_filename1
> > ca_filename2 => aa_filename2
> > ca_filename3 => aa_filename3
> > ca_filename4 => aa_filename4
>
> > Questions:
> > How do I get the desired output without resorting to the 'double pop'?
> > How do I get rid of the extra "=>"?
>
> > Thanks in advance.
>
> > #!/usr/bin/perl
> > use warnings;
> > use strict;
>
> > my $ca_path = "log_ca.txt";
> > my $aa_path = "log_aa.txt";
>
> > my %final_report;
> > my @ca_filenames;
> > my @aa_filenames;
>
> > open (CAFILE, $ca_path) or die $!;
> > my @ca_files = ;
>
> > open(AAFILE, $aa_path) or die $!;
> > my @aa_files = ;
>
> > #sort arrays
> > my @ca_files_sorted = sort @ca_files;
> > my @aa_files_sorted = sort @aa_files;
>
> > my $total_items = @ca_files_sorted;
>
> > foreach(@ca_files_sorted){
> > s/[\r\t\n]+//; #Remove carriage returns and new lines
> > my @temp = split (/\d+->/, $_);
>
> Assuming that $_ contains '111111111->ca_filename1' then @temp now
> contains ( '', 'ca_filename1' ).
>
> > push @ca_filenames, @temp;
> > }
>
> At the end of the loop @ca_filenames will contain:
>
> ( '', 'ca_filename1', '', 'ca_filename2', '', 'ca_filename3', '',
> 'ca_filename4' )
>
> You need to store only the string after /\d+->/:
>
> foreach ( @ca_files_sorted ) {
> s/\s+\z//; # Remove all trailing whitespace
> push @ca_filenames, /\d+->(.+)/;
>
> }
> > foreach(@aa_files_sorted){
> > s/[\r\t\n]+//; #Remove carriage returns and new lines
> > my @temp = split (/\d+->/, $_);
> > push @aa_filenames, @temp;
> > }
>
> As above, at the end of the loop @aa_filenames will contain:
>
> ( '', 'aa_filename1', '', 'aa_filename2', '', 'aa_filename3', '',
> 'aa_filename4' )
>
> > ###problems start here
> > #why do I need to put pop@... twice?
>
> Because @ca_filenames has twice as many elements as @ca_files_sorted
> (where $total_items was derived from.)
>
> > #otherwise it won't display all items.
> > #I don't put that this is the outcome.
> > #CA FILENAME => AA_FILENAME
> > # =>
> > #ca_filename3 => aa_filename3
> > #ca_filename4 => aa_filename4
>
> > for (1..$total_items){
> > $final_report{ pop @ca_filenames } = pop @aa_filenames;
> > $final_report{ pop @ca_filenames } = pop @aa_filenames;
> > }
>
> And so you end up with a hash that has a key '' and a corresponding
> value ''.
>
> You could accomplish the same thing more simply with a hash slice (no
> loop required):
>
> @final_report{ @ca_filenames } = @aa_filenames;
>
> > #why do I get the '=>' symbol there?
> > print "CA FILENAME => AA_FILENAME\n";
> > foreach (sort { $a cmp $b } keys(%final_report) ){
> > print "$_ => $final_report{$_}\n";
> > }
>
> John
> --
> Perl isn't a toolbox, but a small machine shop where you
> can special-order certain sorts of tools at low cost and
> in short order. -- Larry Wall


--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/