如何计算散列中存在的键数?

How to count the number of keys that exist in a hash?

我正在处理一个包含制表符分隔序列的输入文件。序列组由换行符分隔。该文件如下所示:

    TAGC     TAGC     TAGC     HELP
    TAGC     TAGC     TAGC 
    TAGC     HELP  
    TAGC 

这是我的代码:

    use strict; 
    use warnings; 

    open(INFILE, "<", "/path/to/infile.txt") or die $!; 

    my %hash = ( 
            TAGC => 'THIS_EXISTS', 
            GCTA => 'THIS_DOESNT_EXIST',
    ); 

    while (my $line = <INFILE>){ 
            chomp $line; 
            my $hash; 
            my @elements = split "\t", $line; 
            open my $out, '>', "/path/to/outfile.txt" or die $!; 
            foreach my $sequence(@elements){ 
                  if (exists $hash{$sequence}){ 
                         print $out ">$sequence\n$hash{$sequence}\n"; 
                   } 
                   else 
                   } 
                         $count++; 
                         print "Doesn't exist ", $count, "\n"; 
                   }
            } 
     } 

如何在打印前判断存在多少个序列?我需要将该信息放入输出文件的名称中。

理想情况下,我会有一个可以包含在文件名中的变量。不幸的是,我不能只使用@elements 的标量,因为有些序列不会被打印出来。当我尝试将存在的键放入一个数组然后打印该数组的标量时,我仍然没有得到我需要的结果。这是我尝试过的(所有需要全局的变量都是):

  open my $out, '>', "/path/to/file.$number.txt" or die $!;    
  foreach my $sequence(@elements){ 
            if (exists $hash{$sequence}){ 
                  push(@Array, $hash{$sequence}, "\n"); 
                  my $number = @Array; 
                  print $out ">$sequence\n$hash{$sequence}\n"; 
             #.... 

感谢您的帮助。真的很感激。

最简单的方法是跟踪您在变量中打印了多少键,一旦循环完成,只需使用您计算出的数字重命名文件即可。 Perl 带有一个内置函数来执行此操作。代码将是这样的:

use strict; 
use warnings; 

open(INFILE, "<", "/path/to/infile.txt") or die $!; 

my %hash = ( 
        TAGC => 'THIS_EXISTS', 
        GCTA => 'THIS_DOESNT_EXIST',
);
my $ammt;

while (my $line = <INFILE>){ 
        chomp $line; 
        my $hash; 
        my @elements = split "\t", $line; 
        open my $out, '>', "/path/to/outfile.txt" or die $!; 
        foreach my $sequence(@elements){ 
              if (exists $hash{$sequence}){ 
                     print $out ">$sequence\n$hash{$sequence}\n";
                     $ammt++;
               } 
               else 
               }
               print "Doesn't exist ", $count, "\n"; 
               }
        } 
}

rename "/path/to/outfile.txt", "/path/to/outfile${ammt}.txt" or die $!;

我删除了 $count 变量,因为它没有在您的代码中声明(严格会抱怨)。 Here's rename 的官方文档。由于它 returns True 或 False,您可以检查它是否成功。

顺便提一下:

push(@Array, $hash{$sequence}, "\n");

正在存储两项($hash{$sequence}\n),因此计数将是应有的两倍。

my $sequences = grep exists $hash{$_}, @elements;
open my $out, '>', "/path/to/outfile_containing_$sequences.txt" or die $!; 

在列表上下文中,grep 按标准过滤列表;在标量上下文中,它 returns 满足标准的元素计数。