Reputation: 13
I'm new to perl, and I have trouble using a Cartesian Product. I already found the modules Set::CrossProd and Math::Cartesian::Product, but I can get them to work for my usage because I need to produce an array of.
What I exactly want to do is from a genetic sequence (of variable length, depend on the input), let use for example ARDN, i want all the possible output sequence of this. I say all because in fact, R means A or G, D means A, G or T and N mean A, T, C, or G.
So what i did, is have an hash of array for the different possible letters, then translate with a loop the input sequence into an Array of array. So in our example, I should get :
@AoA = (
["A"],
["A", "G"],
["A", "G", "T"],
["A", "T", "C", "G"],
);
however, it seems that I get an array of scalar, because when I print it, I have the letters that are displayed.
my code :
my %alphabet = ( #not complete for simplification
A => ["A"],
D => ["A" , "G", "T"],
N => ["A", "T", "C", "G"],
);
my @test = (
["A"],
["A" , "G", "T"],
["A", "T", "C", "G"],
);
my $seq = <STDIN>;
chomp $seq;
$seq =~ s// /g;
my @sequence = split(" ", $seq, length($seq));
my @AoA;
for (my $i = 0; $i < $#sequence; $i++) {
push (@AoA, @{$alphabet{$sequence[$i]}});
};
print "@test";
print "@AoA";
Output :
ARDN
ARRAY(0x84ea30) ARRAY(0x867780) ARRAY(0x8677f8)
A A G A G T A T C G
What did I do wrong ? Thanks
Upvotes: 1
Views: 109
Reputation: 6553
This looks like a perfect use case for map
, which is great when you need to transform a list of things into a new list of things. The bulk of your code could be reduced to the following example, which, in my opinion, is more elegant and clear.
my $seq = <STDIN>;
chomp($seq);
my @AoA = map { $alphabet{uc($_)} } split(//, $seq);
Upvotes: 0
Reputation: 50190
In perl, an array cannot properly contain another array. Your push
adds the elements of the second list to the array. You should be pushing references to arrays (and then adapt the rest of your code to expect references).
push (@AoA, \@{$alphabet{$sequence[$i]}});
Upvotes: 3