在Hl中将散列哈希打印成矩阵表

时间:2013-08-21 03:22:09

标签: perl

我有这样的数据结构:

#!/usr/bin/perl -w
my $hash = {
             'abTcells' => {
                             'mesenteric_lymph_node' => {
                                                         'Itm2a'   => '664.661',
                                                         'Gm16452' => '18.1425',
                                                         'Sergef'  => '142.8205'
                                                       },

                               'spleen'       =>   {  
                                                       'Itm2a' => '58.07155',
                                                       'Dhx9' => '815.2795',
                                                       'Ssu72' => '292.889'

                                                }
                            }
            };

我想要做的是将其打印成这种格式:

                mesenteric_lymph_node       spleen
Itm2a               664.661                 58.07155
Gm16452             18.1425                 NA
Sergef              142.8205                NA
Dhx9                 NA                     815.2795
Ssu72                NA                     292.889

做什么的方法。

我目前仍然使用以下代码https://eval.in/44207

foreach my $ct (keys %{$hash}) {
     print "$ct\n\n";
     my %hash2 = %{$hash->{$ct}};
       foreach my $ts (keys %hash2) {
       print "$ts\n";
       my %hash3 = %{$hash2{$ts}};
       foreach my $gn (keys %hash3) {
          print "$gn $hash3{$gn}\n";
       }
     }
 }

3 个答案:

答案 0 :(得分:4)

使用Text::Table输出。 Beautify to taste

#!/usr/bin/env perl

use strict;
use warnings;

use Text::Table;

my $hash = {
    'abTcells' => {
        'mesenteric_lymph_node' => {
            'Itm2a'   => '664.661',
            'Gm16452' => '18.1425',
            'Sergef'  => '142.8205'
        },
        'spleen' =>  {
            'Itm2a' => '58.07155',
            'Dhx9' => '815.2795',
            'Ssu72' => '292.889'
        }
    }
};

my $struct = $hash->{abTcells};

my @cols = sort keys %{ $struct };
my @rows = sort keys %{ { map {
    my $x = $_;
    map { $_ => undef }
    keys %{ $struct->{$x} }
} @cols } };

my $tb = Text::Table->new('', @cols);

for my $r (@rows) {
    $tb->add($r, map $struct->{$_}{$r} // 'NA', @cols);
}

print $tb;

输出:

        mesenteric_lymph_node spleen
Dhx9    NA                    815.2795
Gm16452  18.1425              NA
Itm2a   664.661                58.07155
Sergef  142.8205              NA
Ssu72   NA                    292.889

现在,上面的行的顺序与您显示的顺序不同,因为我希望它是一致的。如果您知道所有可能行的集合,那么您可以明确指定另一个顺序。

答案 1 :(得分:1)

首先要将两个哈希分开:

my %lymph_node =  %{ $hash->{abTcells}->{mesenteric_lymph_node} };
my %spleen     =  %{ $hash->{abTcells}->{spleen} };

现在,您有两个包含所需数据的独立哈希值。

我们需要的是所有键的列表。让我们制作一个包含你的密钥的第三个哈希。

my %keys;
map { $keys{$_} = 1; } keys %lymph_node, keys %spleen;

现在,我们可以浏览所有键并打印两个哈希中的每一个的值。如果其中一个哈希值没有数据,我们会将其设置为NA

for my $value ( sort keys %keys ) {
    my $spleen_value;
    my $lymph_nodes_value;
    $spleen_value = exists $spleen{$value} ? $spleen{$value} : "NA";
    $lymph_node_value = exists $lymph_node{$value} ? $lymph_node{$value} : "NA";
    printf "%-20.20s  %-9.5f %-9.5f\n", $key, $lymph_node_value, $spleen_value;
}

printf语句是一种表达数据的好方法。你必须自己创建标题。 ... ? ... : ...语句缩写为if/then/else如果?之前的语句为true,则该值为?:之间的值。否则,该值是:之后的值。

答案 2 :(得分:0)

你的两个内部哈希都有相同的键,所以在其中一个哈希上做foreach以得到键,然后打印两个键。