如何在数组元素中搜索哈希键中的匹配项
Posted
技术标签:
【中文标题】如何在数组元素中搜索哈希键中的匹配项【英文标题】:How to search through array elements for match in hash keys 【发布时间】:2013-05-16 10:52:32 【问题描述】:我有一个数组,其中包含 DNA 序列的唯一 ID(数字)。我已经将我的 DNA 序列放在一个散列中,这样每个键都包含一个描述性标题,它的值就是 DNA 序列。此列表中的每个标题都包含基因信息,并以其唯一的 ID 号为后缀:
唯一 ID:14272
标头(哈希键):PREDICTEDXenopusSiluranatropicalishypotheticalproteinLOCLOCmRNA14272
序列(哈希值):ATGGGTC...
我想循环遍历每个唯一 ID,看看它是否与每个标题末尾的数字(哈希键)匹配,如果是,则将哈希键 + 值打印到文件中。到目前为止,我得到了这个:
my %hash;
@hash@hash_index = @hash_seq;
foreach $hash_index (sort keys %hash)
for ($i=0; $i <= $#scaffoldnames; $i++)
if ($hash_index =~ /$scaffoldnames[$i]/)
print GENE_ID "$hash_index\n$hash$hash_index\n";
close(GENE_ID);
其中唯一 ID 包含在 @scaffoldnames 中。
这行不通!我不确定如何最好地循环遍历哈希和数组以找到匹配项。
我将在下面展开:
上游代码:
foreach(@scaffoldnames)
s/[^0-9]*//g;
#Remove all non-numerics
my @genes = read_file('splice.txt'); #Splice.txt is a fasta file
my $hash_index = '';
my $hash_seq = '';
foreach(@genes)
if (/^>/)
my $head = $_;
$hash_index .= $head; #Collect all heads for hash
else
my $sequence = $_;
$hash_seq .= $sequence; #Collect all sequences for hash
my @hash_index = split(/\n/,$hash_index); #element[0]=head1, element[1]=head2
my @hash_seq = split(/\n/, $hash_seq); #element[0]=seq1, element[1]=seq2
my %hash; # Make hash from both arrays - heads as keys, seqs as values
@hash@hash_index = @hash_seq;
foreach $hash_index (sort keys %hash)
for ($i=0; $i <= $#scaffoldnames; $i++)
if ($hash_index =~ /$scaffoldnames[$i]$/)
print GENE_ID "$hash_index\n$hash$hash_index\n";
close(GENE_ID);
我正在尝试分离 cuffdiff (RNA-Seq) 输出的所有不同表达的基因(通过唯一 ID),并将它们与它们来自的支架(在本例中为表达序列)相关联。
因此我希望我可以隔离每个唯一 ID 并搜索原始 fasta 文件以提取它匹配的标头及其关联的序列。
【问题讨论】:
【参考方案1】:您似乎错过了哈希的意义:它们用于通过键索引您的数据,以便您可以一步访问相关信息,就像您可以使用数组一样。循环遍历每个哈希元素有点破坏了这一点。例如,你不会写
my $value;
for my $i (0 .. $#data)
$value = $data[i] if $i == 5;
您只需这样做
my $value = $data[5];
如果没有关于您的信息来自何处以及您想要什么的更多信息,很难提供适当的帮助,但这段代码应该会有所帮助。
我使用了我认为看起来像您正在使用的单元素数组,并使用 ID (标题的尾随数字)作为键。您可以使用$hash14272
查找ID 14272
的信息。标头为$hash14272[0]
,序列为$hash14272[1]
如果您提供更多关于您的情况的说明,那么我们可以为您提供进一步的帮助。
use strict;
use warnings;
my @hash_index = ('PREDICTEDXenopusSiluranatropicalishypotheticalproteinLOCLOCmRNA14272');
my @hash_seq = ('ATGGGTC...');
my @scaffoldnames = (14272);
my %hash = map
my ($key) = $hash_index[$_] =~ /(\d+)\z/;
$key => [ $hash_index[$_], $hash_seq[$_] ];
0 .. $#hash_index;
open my $gene_fh, '>', 'gene_id.txt' or die $!;
for my $name (@scaffoldnames)
next unless my $info = $hash$name;
printf $gene_fh "%s\n%s\n", @$info;
close $gene_fh;
更新
从您发布的新代码看来,您可以用此代码替换该部分。
它的工作原理是从它找到的每个序列头中获取尾随数字,并使用它作为键来选择一个哈希元素来附加数据。哈希值是标题和序列,都在一个字符串中。如果您有理由将它们分开,请告诉我。
foreach (@scaffoldnames)
s/\D+//g;
# Remove all non-numerics
open my $splice_fh, '<', 'splice.txt' or die $!; # splice.txt is a FASTA file
my %sequences;
my $id;
while (<$splice_fh>)
($id) = /(\d+)$/ if /^>/;
$sequences$id .= $_ if $id;
for my $id (@scaffoldnames)
if (my $sequence = $sequences$id)
print GENE_ID $sequence;
【讨论】:
@Nick:我在答案中添加了一些新代码。我认为它应该适合你。以上是关于如何在数组元素中搜索哈希键中的匹配项的主要内容,如果未能解决你的问题,请参考以下文章
php - 如何在关联数组的数组中搜索多个键/值对并返回匹配项?