povilito
povilito

Reputation: 11

Is it possible to put elements of array to hash in perl?

example of file content:

>random sequence 1 consisting of 500 residues.
VILVWRISEMNPTHEIYPEVSYEDRQPFRCFDEGINMQMGQKSCRNCLIFTRNAFAYGIV
HFLEWGILLTHIIHCCHQIQGGCDCTRHPVRFYPQHRNDDVDKPCQTKSPMQVRYGDDSD;

>random sequence 2 consisting of 500 residues.
KAAATKKPWADTIPYLLCTFMQTSGLEWLHTDYNNFSSVVCVRYFEQFWVQCQDHVFVKN
KNWHQVLWEEYAVIDSMNFAWPPLYQSVSSNLDSTERMMWWWVYYQFEDNIQIRMEWCNI
YSGFLSREKLELTHNKCEVCVDKFVRLVFKQTKWVRTMNNRRRVRFRGIYQQTAIQEYHV
HQKIIRYPCHVMQFHDPSAPCDMTRQGKRMNFCFIIFLYTLYEVKYWMHFLTYLNCLEHR;

>random sequence 3 consisting of 500 residues.
AYCSCWRIHNVVFQKDVVLGYWGHCWMSWGSMNQPFHRQPYNKYFCMAPDWCNIGTYAWK

I need an algorithm to build a hash $hash{$key} = $value; where lines starting with > are the values and following lines are the keys.

What I have tried:

open (DATA, "seq-at.txt") or die "blabla";
@data = <DATA>;
%result = ();
$k = 0;
$i = 0;

while($k != @data) {
    $info = @data[$k]; #istrina pirma elementa
    if(@data[$i] !=~ ">") {
        $key .= @data[$i]; $i++;
    } else {
        $k = $i;
    }
    $result{$key} = $value;
}

but it doesn't work.

Upvotes: 0

Views: 58

Answers (2)

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89557

You don't have to previously use an array, you can directly build your hash:

use strict;
use warnings;
# ^- start always your code like this to see errors and what is ambiguous

# declare your variables using "my" to specify the scope
my $filename = 'seq-at.txt'; 

# use the 3 parameters open syntax to avoid to overwrite the file:
open my $fh, '<', $filename or die "unable to open '$filename' $!";

my %hash;
my $hkey = '';
my $hval = '';

while (<$fh>) {
    chomp; # remove the newline \n (or \r\n)
    if (/^>/) { # when the line start with ">"
        # store the key/value in the hash if the key isn't empty
        # (the key is empty when the first ">" is encountered)
        $hash{$hkey} = $hval if ($hkey);
        # store the line in $hval and clear $hkey
        ($hval, $hkey) = $_;
    } elsif (/\S/) { # when the line isn't empty (or blank)
        # append the line to the key
        $hkey .= $_;
    }
}

# store the last key/val in the hash if any
$hash{$hkey} = $hval if ($hkey);

# display the hash
foreach (keys %hash) {
    print "key: $_\nvalue: $hash{$_}\n\n";
}

Upvotes: 1

sebosp
sebosp

Reputation: 1

It is unclear what you want, the array seems to be the lines subsequent to the random sequence number... If the contenst of a file test.txt are:

Line 1:">"random sequence 1 consisting of 500 residues.
Line 2:VILVWRISEMNPTHEIYPEVSYEDRQPFRCFDEGINMQMGQKSCRNCLIFTRNAFAYGIV
Line 3:HFLEWGILLTHIIHCCHQIQGGCDCTRHPVRFYPQHRNDDVDKPCQTKSPMQVRYGDDSD;

You could try something like:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my $contentFile = $ARGV[0];
my %testHash = ();
my $currentKey = "";

open(my $contentFH,"<",$contentFile);
while(my $contentLine = <$contentFH>){
    chomp($contentLine);
    next if($contentLine eq ''); # Empty lines.
    if($contentLine =~ /^"\>"(.*)/){
            $currentKey= $1;
    }else{
            push(@{$testHash{$currentKey}},$contentLine);
    }
}
print Dumper(\%testHash);

Which results in a structure like this:

seb@amon:[~]$ perl test.pl test.txt
$VAR1 = {
          'random sequence 3 consisting of 500 residues.' => [
                                                               'AYCSCWRIHNVVFQKDVVLGYWGHCWMSWGSMNQPFHRQPYNKYFCMAPDWCNIGTYAWK'
                                                             ],
          'random sequence 1 consisting of 500 residues.' => [
                                                               'VILVWRISEMNPTHEIYPEVSYEDRQPFRCFDEGINMQMGQKSCRNCLIFTRNAFAYGIV',
                                                               'HFLEWGILLTHIIHCCHQIQGGCDCTRHPVRFYPQHRNDDVDKPCQTKSPMQVRYGDDSD;'
                                                             ],
          'random sequence 2 consisting of 500 residues.' => [
                                                               'KAAATKKPWADTIPYLLCTFMQTSGLEWLHTDYNNFSSVVCVRYFEQFWVQCQDHVFVKN',
                                                               'KNWHQVLWEEYAVIDSMNFAWPPLYQSVSSNLDSTERMMWWWVYYQFEDNIQIRMEWCNI',
                                                               'YSGFLSREKLELTHNKCEVCVDKFVRLVFKQTKWVRTMNNRRRVRFRGIYQQTAIQEYHV',
                                                               'HQKIIRYPCHVMQFHDPSAPCDMTRQGKRMNFCFIIFLYTLYEVKYWMHFLTYLNCLEHR;'
                                                             ]
        };

You would be basically using each hash "value" as an array structure, the @{$variable} does the magic.

Upvotes: 0

Related Questions