在脚本

时间:2018-05-15 08:11:44

标签: perl

我有一个从文件中收集的哈希值。下面的脚本将按预期打印所有值(注意我只包含脚本的重要部分,因此打开输入文件时不会添加太宽):

use strict;
use warnings;

my %hash = ();
while (<$fh>) {
  my ($region, $site, $layer) = split;
  push @{$hash{$region}}, "$region $site $layer";
}
foreach my $values(keys %hash) {
  print $values,"\n";
}

我的问题是,我不想根据键打印所有值,我实际上想要分解值并通过告诉perl我想要的东西在不同区域打印它们,而不仅仅是打印{{1 }}

例如,如果我有以下数据:

$values

我实际上希望能够在其他区域使用这些值,并打印如下内容:

North belair layer2
North belair layer3
East Monte layer2
East Vista layer3

将打印:

  

belair有图层:layer2 layer3

     

Monte有图层:layer2

     

Vista有图层:layer3

print "$site has layers: $layer"

然后将打印:

  

North有站点:belair和layers:layer2 layer3

     

East有网站:Monte Vista和图层:layer2 layer3

当我运行多个print "$region has sites, $site and $site has layers: $layer"; 循环时,我得到重复的结果,我不知道要转到哪个方向。我所做的每项搜索都只向我展示了如何为foreach

打印所有$values

2 个答案:

答案 0 :(得分:3)

对于直接问题:迭代键并将每个值拆分为变量

foeach my $region (sort keys %hash) {
    my ($region, $site, $layer) = split ' ', $region;
    ...
}

然后您可以使用它进行首次打印。

然而,有两个笔记是有序的。

为什么$region是键的一部分?相反,为什么不

...
push @{$hash{$region}}, "$site $layer";

以便您将网站和图层与区域相关联。

更重要的是,区域中的条目具有相同的站点,并且您显然需要区域内站点的所有层。那么你可能想要一个嵌套结构

%hash = ( region => { site => [ layer, ... ], ... }, ... )

可以填充

while (<$fh>) {
    my ($region, $site, $layer) = split;
    push @{$hash{$region}->{$site}}, $layer;
}

通过这种方式,您可以对区域内的所有图层进行第二次打印

foreach my $region (sort keys %hash) {
    print "$region has sites: ", 
        join(' and ', keys %{$hash{$region}}), ", with layers: ";
    foreach my $site (keys %{$hash{$region}}) {
        print "@{$hash{$region}->{$site}} "
    }
    say ''; 
}

打印什么

East has sites: Vista and Monte, with layers: layer3 layer2 
North has sites: belair, with layers: layer2 layer3 

答案 1 :(得分:3)

my %sites;
my %regions;
while (<>) {
   my ($region_id, $site_id, $layer_id) = split;

   # Use hashes instead of arrays to remove duplicates.    
   ++$sites{$site_id}{layers}{$layer_id};
   ++$regions{$region_id}{layers}{$layer_id};
   ++$regions{$region_id}{sites}{$site_id};
}

# "Flatten" hashes into sorted arrays of unique elements.
for my $site_id (keys(%sites)) {
   my $site = $sites{$site_id};
   $site->{layers} = [ sort keys(%{ $site->{layers} }) ];
}

for my $region_id (keys(%regions)) {
   my $region = $regions{$region_id};
   $region->{layers} = [ sort keys(%{ $region->{layers} }) ];
   $region->{sites}  = [ sort keys(%{ $region->{sites}  }) ];
}

# Now do what we want to do.
for my $site_id (sort keys(%sites)) {
   my $site = $sites{$site_id};
   print "$site_id has layers @{ $site->{layers} }\n";
}

for my $region_id (sort keys(%regions)) {
   my $region = $regions{$region_id};
   print "$region_id has sites @{ $region->{sites} } and layers @{ $region->{layers} }\n";
}