代码之家  ›  专栏  ›  技术社区  ›  Mr Keystrokes

如何引用哈希数组的哈希以比较值

  •  0
  • Mr Keystrokes  · 技术社区  · 8 年前

    my %hash = (
        'hsa_circ_0024017|chr11:93463035-93463135+|NM_033395|KIAA1731  FORWARD' => [ 
            { 
              'energy' => '-4.3', 
              'spacer' => 'AGGCACC', 
              'end' => '97', 
              'start' => '81' 
            } 
        ],
        'hsa_circ_0067224|chr3:128345575-128345675-|NM_002950|RPN1  FORWARD' => [ 
            { 
              'energy' => '-4.4', 
              'spacer' => 'CAGT', 
              'end' => '17', 
              'start' => '6' 
            }, 
            { 
              'energy' => '-4.1', 
              'spacer' => 'GTT', 
              'end' => '51', 
              'start' => '26' 
            }, 
            { 
              'energy' => '-4.1', 
              'spacer' => 'TTG', 
              'end' => '53', 
              'start' => '28' 
            } 
        ],
        ...
    );
    

    如何访问哈希的内容,以便能够比较循环中的内容?

    对于每个父散列(hsa\u circ…),我想将子散列(间隔符)一起比较。原谅我,我在努力把这个词说对。这当然是数据的一个小样本。简而言之,我的目标是检测具有相同间隔的哈希数组,如果它们具有相同的间隔,那么我想选择具有相同间隔的哈希数组 能量分数。

    3 回复  |  直到 8 年前
        1
  •  1
  •   zdim    8 年前

    问题是:每个arrayref中可能有一组hashref具有相同的 垫片 价值在每个这样的组中,hashref具有最低的 能量 需要确定,以取代该组。

    大部分工作是在 partition_equal()

    use warnings;
    use strict;
    use List::Util qw(reduce);
    use Data::Dump qq(dd);
    
    # Test data: two groups of equal-spacer hashrefs, in the first array only
    my %hash = (  
        kA => [
            { 'energy' => -4.3, 'spacer' => 'AGGCACC' },
            { 'energy' => -2.3, 'spacer' => 'AGGCACC' },
            { 'energy' => -3.3, 'spacer' => 'CAGT' },
            { 'energy' => -1.5, 'spacer' => 'GTT' },
            { 'energy' => -2.5, 'spacer' => 'GTT' },
        ],
        kB => [
            { 'energy' => -4.4, 'spacer' => 'CAGT' },
            { 'energy' => -4.1, 'spacer' => 'GTT' },
            { 'energy' => -4.1, 'spacer' => 'TTG' },
        ],
    );
    #dd \%hash;
    
    for my $key (keys %hash) {
        my ($spv, $unique) = partition_equal($hash{$key});
        next if not $spv;
        # Extract minimum-energy hashref from each group and add to arrayref
        # $unique, so that it can eventually overwrite this key's arrayref
        foreach my $spacer (keys %$spv) {
            my $hr_min = reduce { 
                $a->{energy} < $b->{energy} ? $a : $b 
            } @{$spv->{$spacer}};
            push @$unique, $hr_min;
        }
        # new: unique + lowest-energy ones for each equal-spacer group   
        $hash{$key} = $unique  if keys %$spv;
    }    
    dd \%hash;
    
    # Sort array and compare neighbouring elements (hashrefs) 
    sub partition_equal {
        my $ra = shift;
        my @sr = sort { $a->{spacer} cmp $b->{spacer} } @$ra;
    
        # %spv:    spacer value => [ hashrefs with it ], ...
        # @unique: hasrefs with unique spacer values    
        my (%spv, @unique);
    
        # Process first and last separately, to not have to test for them
        ($sr[0]{spacer} eq $sr[1]{spacer})
            ? push @{$spv{$sr[0]{spacer}}}, $sr[0]
            : push @unique, $sr[0];
        for my $i (1..$#sr-1) {
            if ($sr[$i]{spacer} eq $sr[$i-1]{spacer}  or 
                $sr[$i]{spacer} eq $sr[$i+1]{spacer}) 
            {
                push @{$spv{$sr[$i]{spacer}}}, $sr[$i]
            }
            else { push @unique, $sr[$i] }
        }
        ($sr[-1]{spacer} eq $sr[-2]{spacer})
            ? push @{$spv{$sr[-1]{spacer}}}, $sr[-1]
            : push @unique, $sr[-1];
    
        return if not keys %spv;
        return \%spv, \@unique;
    }
    

    输出

    kA => [
            { energy => -3.3, spacer => "CAGT" },
            { energy => -2.5, spacer => "GTT" },
            { energy => -4.3, spacer => "AGGCACC" },
          ],
    kB => [
            { energy => -4.4, spacer => "CAGT" },
            { energy => -4.1, spacer => "GTT" },
            { energy => -4.1, spacer => "TTG" },
          ],
    

    arrayrefs内的顺序未保持;新的arrayref首先具有具有唯一间隔值的hashref,然后是具有最低能量值的hashref(对于具有相同间隔值的每个原始组)。

        2
  •  0
  •   hoffmeister    8 年前

    这样地

    $_=$hash{'hsa_circ_0024017|chr11:93463035-93463135+|NM_033395|KIAA1731  FORWARD'}->[0]{energy};
    
    print  $_ ."\n";
    

    所以是 $this{hash}->[array\u ref]{hash]

        3
  •  0
  •   ikegami Gilles Quénot    8 年前
    for my $line (keys(%by_line)) {
       my $spacer_defs = $by_line{$line};
       ...
    }
    

    for my $spacer_defs (values(%by_line)) {
       ...
    }
    

    将为您获取(引用到)数组(引用到) 垫片定义

       my %uniq_spacer_defs;
       for my $spacer_def (@$spacer_defs) {
          my $spacer = $spacer_def->{spacer};
          $uniq_spacer_defs{$spacer} = $spacer_defs
             if !$uniq_spacer_defs{$spacer}
             || $uniq_spacer_defs{$spacer}{energy} < $spacer_def->{energy};
       }
    
       @$spacer_defs = values(%uniq_spacer_defs);
    

    笔记:

    • “垫片定义”的顺序可能会改变。如果出现问题,请更换

      @$spacer_defs = values(%uniq_spacer_defs);
      

      具有

      @$spacer_defs = grep { $uniq_spacer_defs{$_->{spacer}} == $_ } @$spacer_defs;
      
    • 如果两个间隔定义具有相同间隔和相同能量,则保留遇到的第一个间隔定义。