Re: How to make a array of hashes and search them
by moritz (Cardinal) on Feb 17, 2012 at 10:35 UTC
|
my %IDs;
# when reading the ID file, for each line do something like
$IDs{$current_id} = [];
# and then for each line in the four other files:
while (my $line = <$file>) {
my ($id, $value) = split / /, $line;
push @{$IDs{$id}}, $value
}
# and at the very end, print them all out:
for my $id (sort keys %IDs) {
print "$id: ", join(', ', @{$IDs{$id}}), "\n";
}
See also: perlintro, perlreftut.
If you want to keep track about which file contains which ID, you should use something like $IDs{$id}[$file_number] = $value instead of using push.
| [reply] [d/l] [select] |
Re: How to make a array of hashes and search them
by Anonymous Monk on Feb 17, 2012 at 10:42 UTC
|
| [reply] |
Re: Searching Multiple files and print it in order
by JavaFan (Canon) on Feb 17, 2012 at 10:46 UTC
|
You can do this in the shell:
grep -F -f file1 file2 file3 file4 file5
Although this assumes that an ID will not match a value.
Untested Perl solution:
my %matches = map {/(.*)/, 1}, do {local @ARGV = "file1"; <>};
local @ARGV = ("file2", "file3", "file4", "file5");
while (<>) {
/^(\S+)/ && $matches{$1} && print
}
| [reply] [d/l] [select] |
Re: How to make a array of hashes and search them
by Anonymous Monk on Feb 17, 2012 at 17:30 UTC
|
Thanks a ton for the help.
I wrote as per the pseudo code. it worked but here the problem is for each and every ID its print same values in all four columns. I have no clue why it is happening.so i need more help.
Thanking you in advance.
Regards
Deepak
foreach $file (@files)
{
open(INP,"$file") or die "Cannot open file :$!\n";
while (<INP>)
{
chomp;
@line = split "\t",$_;
if(exists $trans{$line[0]})
{
$array[$j] = $line[1];
$trans{$line[0]} = \@array;
}
}
close(INP);
$j++;
}
foreach $key (keys %trans)
{
print OUT "$key\t";
foreach(@{$trans{$key}})
{
print OUT "$_\t";
}
print OUT "\n";
}
| [reply] [d/l] |
|
There seems to be only one global variable with name @array. Thus \@array always returns a reference to the same array, which is probably not what you want.
The solution is to use strict; and declare your variables in appropriate scopes.
| [reply] [d/l] [select] |
|
As moritz said, your @array appears to be global, so it's not getting recreated each time through your loop, and all your hash keys are getting assigned a reference to the same array. Here's how I'd rewrite your loop to eliminate that array and clarify some things:
my $j = 0; # file/column number
foreach $file (@files){
open(INP,"$file") or die "Cannot open file :$!\n";
while (<INP>){
chomp;
my($key,$value) = split "\t";
if(exists $trans{$key}){
$trans{$key}[$j] = $value;
}
}
close(INP);
$j++;
}
When you split a line into an array and then start accessing the elements directly like $line[0], that's a good sign you might want to split it into named scalars like $key and $value instead, so you don't have to remember later what array index held what. I think it also makes it easier to see what I'm doing there when I assign the $value to the $j-th element of the array pointed to by the $key of the hash.
| [reply] [d/l] [select] |
Re: How to make a array of hashes and search them
by Anonymous Monk on Feb 18, 2012 at 00:19 UTC
|
You can set up "arrays of hashes" or "hashes of arrays" or "anything of anything" because in every case the "thing" that is "in the (array or hash)" is either a "scalar" or "a reference." The magic bean here is, "a reference," because "a reference" can refer to anything. An array, a hash, or even for that matter another reference or a scalar. Very complex structures are built one brick at a time. | [reply] |
Re: How to make a array of hashes and search them
by pdeepak (Initiate) on Feb 17, 2012 at 11:11 UTC
|
Thank you moritz.
Ya the code works fine but the problem is with the IDs which are not present in say two of the files. I want to print the value as 0. So if the file 1 and file 3 have an id present and its absent in 2 and 4. it should print
ID </t> value1 <\t> 0 <\t> value3 <\t> 0 <\n>.
The other thing is i want to know how can i iterate through files and make the hashes..??
sorry for the trouble
| [reply] |
|
In that case, what you probably want is a hash of arrays, rather than an array of hashes. You want a hash keyed on the unique IDs in your first file, and values consisting of 4-element arrays. Then you can loop through your hash a second time and print out all key/value pairs that have something other than zero in one of their value elements.
Give that a shot, and if you have trouble, post the code so we can help with it. Pseudo-code would look something like this:
instantiate a hash
open file of unique keys
while read a line
get the key from it
make it a key in your hash, with its value being a reference to an a
+rray containing four zeros
for N = 1 to 4
open file1
while read a line
split the key and value out of it
if the key exists in your hash
assign the value to your hash as the Nth element of an array
+ referred to by this key
if the key doesn't exist
skip it or error, depending on your design
for each key in the hash
if any of its array's elements are non-zero
print the key and array elements joined by tabs
| [reply] [d/l] |
A reply falls below the community's threshold of quality. You may see it by logging in. |