Andrej Kastrin wrote:
Dear Perl users,
below is three column, vertical bar separated file. First column refers
to ID number, second designates name and the last one refers to
corresponding value. There are 8 possible names: A, B, C, D, E, F, G and
H (only first seven preset in my dataset)
1 | C | 0.404
1 | D | 0.824
1 | E | 1.761
1 | F | 0.148
1 | G | 1.860
2 | A | 1.420
2 | B | 0.571
2 | C | 0.467
2 | D | 1.824
3 | A | 0.191
Now I have to produce the following output.
1 | 0 | 0 | 0.404 | 0.824 | 1.761 | 0.148 | 1.860 ## 2 zeroes
following ID number while there are no A and B names referring to ID 1
2 | 1.420 | 0.571 | 0.467 | 1.824 | 0 | 0 | 0 | 0 | 0 ## 4 zeroes at
the end while the are no E, F, G, H names referring to ID 2
3 | 0.191 | 0 | 0 | 0 | 0 | 0 | 0 | 0
My code:
####################################
#!/usr/bin/perl
use strict;
use warnings;
my %hash = ();
while (<>) {
my ($id, $name, $value) = split;
push( @{$hash{$id}}, $value);
}
foreach my $id (sort keys %hash) {
print "$id @{$hash{$id}}\n";
}
####################################
which produce the output below. I have no idea how to place zeroes,
where there are no entry for particular name.
1 0.404 0.824 1.761 0.148 1.860
2 1.420 0.571 0.467 1.824
3 0.191
Thanks in advance for any suggestion,
Andrej
Let autovivication do the work for you. If you assign to an array
element that doesn't exist, it does:
use strict;
use warnings;
use Data::Dumper;
local $_ = q{
1 | C | 0.404
1 | D | 0.824
1 | E | 1.761
1 | F | 0.148
1 | G | 1.860
2 | A | 1.420
2 | B | 0.571
2 | C | 0.467
2 | D | 1.824
3 | A | 0.191
};
my %ids;
my %code;
@code{('A'..'G')} = (0..6);
while (m/^\s*(.*?)\s*$/mg) {
my ($id, $name, $value) = split /\s*\|\s*/, $1;
$ids{$id}->[$code{$name}] += $value;
}
print Dumper(\%ids), "\n";
__END__
The %ids hash contains the data, and the %code hash associates names
with array positions, so $code{$name} is a position in an array.
Each $ids{$id} item is autovivified by "+= $value," and each anonymous
array in %ids is autovivified by "->[$code{$name}]."
Without autovivication, this would have been a larger program, but why
do that?
:)
PS.
You can probably figure out how to format the data for output.
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>