Perl 如何创建和遍历(深度为n)的散列,其中深度为n的值是整数?

Perl 如何创建和遍历(深度为n)的散列,其中深度为n的值是整数?,perl,hash,bioinformatics,Perl,Hash,Bioinformatics,我想在描述的数据结构中存储大小为n的DNA序列。每个散列可以包含具有散列值的键C、G、A、T。这些散列值将是完全相同类型的散列-它们将有四个键,C、G、A、T,它们将有散列值 对于n个级别的散列,此结构是一致的。但是,最后一级哈希值将改为整数值,表示从级别1到级别n的序列计数 给定数据('CG','CA','TT','CG'),表明序列CG,CA和TT发生两次,一次和一次。对于该数据,深度为2 这将产生一个散列: %根=('C'=>{'G'=>2,'A'=>1},'T'=>{'T'=>1}) 如

我想在描述的数据结构中存储大小为n的DNA序列。每个散列可以包含具有散列值的键C、G、A、T。这些散列值将是完全相同类型的散列-它们将有四个键,C、G、A、T,它们将有散列值

对于n个级别的散列,此结构是一致的。但是,最后一级哈希值将改为整数值,表示从级别1到级别n的序列计数

给定数据('CG','CA','TT','CG'),表明序列CG,CA和TT发生两次,一次和一次。对于该数据,深度为2

这将产生一个散列: %根=('C'=>{'G'=>2,'A'=>1},'T'=>{'T'=>1})


如何从数据中创建此哈希?

以下操作应该有效:

use Data::Dumper;

my %data;
my @sequences = qw(CG CG CA TT);

foreach my $sequence (@sequences) {
    my @vars = split(//,$sequence);
    $data{$vars[0]} = {} if (!exists($data{$vars[0]}));
    my $startref = $data{$vars[0]};
    for(my $i = 1; $i < $#vars; $i++) {
    $startref->{$vars[$i]} = {} if (!exists($startref->{$vars[$i]}));
    $startref = $startref->{$vars[$i]};
    }
    $startref->{$vars[$#vars]}++;
}

print Dumper(\%data);

以下方面应起作用:

use Data::Dumper;

my %data;
my @sequences = qw(CG CG CA TT);

foreach my $sequence (@sequences) {
    my @vars = split(//,$sequence);
    $data{$vars[0]} = {} if (!exists($data{$vars[0]}));
    my $startref = $data{$vars[0]};
    for(my $i = 1; $i < $#vars; $i++) {
    $startref->{$vars[$i]} = {} if (!exists($startref->{$vars[$i]}));
    $startref = $startref->{$vars[$i]};
    }
    $startref->{$vars[$#vars]}++;
}

print Dumper(\%data);

您需要的是一个函数
get_node($tree,'C','G')
返回对“CG”的哈希元素的引用。然后您可以只增加引用的标量

sub get_node {
   my $p = \shift;
   $p = \( ($$p)->{$_} ) for @_;
   return $p;
}

my @seqs = qw( CG CA TT CG );

my $tree;
++${ get_node($tree, split //) } for @seqs;
问题是,这个函数已经存在为s
DiveRef

use Data::Diver qw( DiveRef );

my @seqs = qw( CG CA TT CG );

my $tree = {};
++${ DiveRef($tree, split //) } for @seqs;
在这两种情况下

use Data::Dumper qw( Dumper );
print(Dumper($tree));
印刷品

$VAR1 = {
          'T' => {
                   'T' => 1
                 },
          'C' => {
                   'A' => 1,
                   'G' => 2
                 }
        };

您需要的是一个函数
get_node($tree,'C','G')
返回对“CG”的哈希元素的引用。然后您可以只增加引用的标量

sub get_node {
   my $p = \shift;
   $p = \( ($$p)->{$_} ) for @_;
   return $p;
}

my @seqs = qw( CG CA TT CG );

my $tree;
++${ get_node($tree, split //) } for @seqs;
问题是,这个函数已经存在为s
DiveRef

use Data::Diver qw( DiveRef );

my @seqs = qw( CG CA TT CG );

my $tree = {};
++${ DiveRef($tree, split //) } for @seqs;
在这两种情况下

use Data::Dumper qw( Dumper );
print(Dumper($tree));
印刷品

$VAR1 = {
          'T' => {
                   'T' => 1
                 },
          'C' => {
                   'A' => 1,
                   'G' => 2
                 }
        };

我真的没有得到你想要的。也没有明显的问题!你想构造一个基数搜索trie吗?我真的没有得到你想要的。也没有明显的问题!您正在尝试构造基数搜索trie吗?您可以说
$hash{key}/={}
,而不是
$hash{key}={}如果!存在$hash{key}
。这并不完全相同(因为它检查
定义的$hash{key}
而不是
是否存在
),但是
存在
定义的
(据我所知)的主要优点是
/=
如果定义了
$hash{key}
但有一个值
未定义
,则
/=/code>将失败。我发现
/=
更容易阅读。你可以说
$hash{key}/={}
而不是
$hash{key}={}如果!存在$hash{key}
。这并不完全相同(因为它检查
定义的$hash{key}
而不是
是否存在
),但是
存在
定义的
(据我所知)的主要优点是
/=
如果定义了
$hash{key}
但有一个值
未定义
,则
/=/code>将失败。我发现
/=
更容易阅读。YMMV。