Perl哈希表超过2维

时间:2014-12-23 13:05:29

标签: perl multidimensional-array hashtable

我正在尝试创建一个包含6个维度的哈希表:哈希表哈希表的哈希表。等等

我从本地文件中获取数据(通过使用REGEX和split函数)。我得到的数据如下:

northPartner1;southServiceCall1;northService1;nbNorthCall1;nbSouthCall1

我想将数据存储在许多哈希表中以使用它们来创建HTML数组。我对哈希表不太满意它对我来说是一个新概念。 问题是我没有实现创建具有多个维度的哈希表。

我成功地做了类似的事情:

#get the data
my $serviceN;
my $serviceS;
my $partnerN;
my $nbCallN;
my %northServices= () ;
my %northCall= ();

open (TraficFile, "$date/volumetries.csv") || die "Can't open: $!";
while(defined($_=<TraficFile>)) {
    my @champsOutput = split(/\;/);
    #get services.
    if ($champsOutput[4]=~/Service Call/i){next;}
    if ($champsOutput[4]=~/.*@/) {
        ($serviceS, $serviceN) = split(/@/,$champsOutput[4]);
        $partnerN = $champsOutput[0];

    }#endif
    $nbCallN = $champsOutput[5];
    print "nb : $nbCallN \n";

    $northServices{$serviceN}{$partnerN}++;
}#while 
#Print result
foreach $serviceN (keys %northServices){
    print ('***'," $serviceN ",'***',"\n");
foreach my $partnerN ( keys %{ $northServices{$serviceN} } ){
    print "     $partnerN \n";
    }
}

我为每个North Service提供North Partners的名称, 但是我想添加这样的哈希表:

$northServices={

    'nameNorthService1' => {
         'nameNorthPartner1' => 'numberOfNorthCall' => 'nameSouthService1' => 'numberOfCall',
=> 'nameSouthService2' => 'numberOfCall',
=> 'nameSouthService3' => 'numberOfCall',

         'nameNorthPartner2' => 'numberOfNorthCall' => 'nameSouthService1' => 'numberOfCall',
=> 'nameSouthService2' => 'numberOfCall',
    }   
    'nameNorthService2' => {
         'nameNorthPartner1' => 'numberOfNorthCall' => 'nameSouthService1' => 'numberOfCall',
    }
 ...
}

numberOfNorthCall分为许多南方服务,每个服务都有numberOfCall

我真的不知道如何创建其他哈希表来封装所有这些数据,就像上面的模型一样。 我试图在while()中创建另一个哈希表,例如:

$northCall{$nbCallN} = $nbCallN;
$serviceNord{$serviceN}{$partnerN}{$northCall{$nbCallN}}++;

我也试图创建引用:

my $rec = {};
$serviceNord{$serviceN}{$partnerN} = $rec;
$rec->{$nbCallN}++;

这似乎是错误的方式,但我找不到任何可以帮助我创建超过两个维度的哈希表。

如果你知道某种方式,请不要犹豫。

1 个答案:

答案 0 :(得分:2)

首先 - 我建议你尝试做一些完全过于复杂的事情。虽然你可以做散列哈希哈希等等,但这将是非常痛苦的。 但是,我认为问题的根源在于,因为您误解了->=>之间的区别。前者取消引用哈希值。后者在功能上等同于逗号。

但从根本上说 - 你没有多维哈希 - 你有一个哈希引用的顶级哈希。

如果你这样做:

use strict;
use warnings;

my %hash;

$hash{firstlayer}{secondlayer}++;
print $hash{firstlayer};

您将获得哈希引用。

但是,我认为您可能要考虑的是停止使用复杂的嵌套哈希,而是尝试将对象组合在一起。 (不要推迟 - 对象基本上是复杂的数据结构,可能包含一些代码)。

以声明方式创建嵌套哈希:

use strict;
use warnings;
use Data::Dumper;

my $value = "value";

my $services = {
    key1 => $value,
    key2 => {
        subkey  => $value,
        subkey2 => $value,
    },
    key3 => {
        subkey1 => {
            subsubkey1 => $value,
            subsubkey2 => $value,
        },
    },
};

print Dumper \$services;

您还可以通过以下方式添加/访问:

   print $services->{key3}->{subkey1}->{subsubkey2};

如果您使用%sigil创建了它,例如

my %services = (
#NOTE - different bracket too!

那么

print $services{key3}{subkey1}{subsubkey2};

它们在功能上相似 - 关键区别在于&#39; - &gt;&#39;告诉perl这是一个参考。您使用哪种样式更多的是在代码中更有意义的问题。

但我仍然建议考虑做OO风格,并创建一个具有属性的对象。 (对象基本上是哈希,但让你做一些更有趣的事情)

#MyService.pm

use strict;
use warnings;

package MyService;

sub new {
    my ( $class ) = @_;
    my $self = {};
    bless ( $self, $class ); 
    return $self;
}

sub set_name { 
    my ( $self, $name ) = @_;
    $self -> {name} = $name;
}

sub add_partner { 
    my ( $self, $partner ) = @_;
    push ( @{ $self -> {partners} }, $partner ); 
}

sub get_partners {
    my ( $self ) = @_;
    return @{ $self -> {partners} };
}

然后你可以:

use strict;
use warnings;

use MyService;

my @services;
my $service = MyService -> new();
push ( @services, $service );

$service -> set_name ( 'nameNorthService1' );