如何在数组元素中搜索哈希键中的匹配项

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 - 如何在关联数组的数组中搜索多个键/值对并返回匹配项?

如果存储在键中的值匹配,如何在 Spark 中合并两个 RDD

如何检查常规数组/哈希/集合/列表中的元素?

如何从任何对象键中过滤不区分大小写的对象数组

如何在 C# 中搜索字符串数组中的子字符串

如何搜索包含 JSON 数组的 SQL 列