Arrays 在一场比赛中获得准确的比赛,但有一个转折点

Arrays 在一场比赛中获得准确的比赛,但有一个转折点,arrays,perl,hash,Arrays,Perl,Hash,我有一些事情我无法理解 假设我有一个用于接收和拨号的电话列表,如下所示。还指定了起始位置和结束位置 Country1 Country2 number1 number2 USA_Chicago USA_LA 12 14 AUS_Sydney USA_Chicago 19 15 AUS_Sydney USA_Chicago

我有一些事情我无法理解

假设我有一个用于接收和拨号的电话列表,如下所示。还指定了起始位置和结束位置

Country1        Country2           number1           number2
USA_Chicago     USA_LA             12                14
AUS_Sydney      USA_Chicago        19                15
AUS_Sydney      USA_Chicago        22                21
CHI_Hong-Kong   RSA_Joburg         72                23
USA_LA          USA_Chigaco        93                27
现在我想做的就是删除所有重复项,只提供与国家相关的密钥和分配给它的每个数字,但这对数字必须是双向的

换句话说,我需要把结果拿回来,然后像这样打印出来

USA_Chicago-USA_LA         27    93   12    14
Aus_Sydney-USA_Chicago     19    15   22    21
CHI_Hong-kong-RSA_Joburg   72    23
我已经尝试了很多方法,包括一个普通的哈希表,结果看起来不错,但是它不能实现双向,所以我将得到这个结果

USA_Chicago-USA_LA         12    14
Aus_Sydney-USA_Chicago     19    15   22    21
CHI_Hong-kong-RSA_Joburg   72    23
USA_LA-USA_Chicago         93    27
因此,重复删除以一种方式工作,但因为有另一个方向,它不会删除重复的“USA_LA-USA_Chicago”,它已经作为“USA_Chicago-USA_LA”存在,并将在SWOPED名称下存储相同的数字

我上次尝试的哈希表是这样的。(不完全是因为我毁了这一部分,不得不为这篇文章重写)


因此,如果A-B和B-A都存在,则只使用一个,但将要删除的键中的值分配给剩余的键。我基本上需要做的是消除任何方向上的任何重复键,但将的值指定给剩余的键。所以A-B和B-A会被认为是重复的,但A-C和B-C不是-_-

只需将目的地正常化即可。我选择把它们分类

use strictures;
use Hash::MultiKey qw();

my @input = (
    'USA_Chicago USA_LA 12 14',
    'AUS_Sydney USA_Chicago 19 15',
    'AUS_Sydney USA_Chicago 22 21',
    'CHI_Hong-Kong RSA_Joburg 72 23',
    'USA_LA USA_Chicago 93 27'
);

tie my %hash, 'Hash::MultiKey';
for my $line (@input) {
    my ($c1, $c2, $n1, $n2) = split / [\s\|]+ /x, $line;
    my %map = ($c1 => $n1, $c2 => $n2);
    push @{ $hash{[sort keys %map]} }, @map{sort keys %map};

}
__END__
(
    ['CHI_Hong-Kong', 'RSA_Joburg'] => [72, 23],
    ['AUS_Sydney', 'USA_Chicago'] => [19, 15, 22, 21],
    ['USA_Chicago', 'USA_LA'] => [12, 14, 27, 93],
)

Perl非常适合创建复杂的数据结构,但是学习如何有效地使用它们需要实践

尝试:

#/usr/bin/env perl
严格使用;
使用警告;
# --------------------------------------
使用字符名qw(:full:short);
使用英语qw(-no_match_vars);#避免正则表达式性能惩罚
使用数据::转储程序;
#使Data::Dumper变得漂亮
$Data::Dumper::Sortkeys=1;
$Data::Dumper::Indent=1;
#设置Data::Dumper的最大深度,零表示无限制
本地$Data::Dumper::Maxdepth=0;
#条件编译调试语句
#看http://lookatperl.blogspot.ca/2013/07/a-look-at-conditional-compiling-of.html
使用常量DEBUG=>$ENV{DEBUG};
# --------------------------------------
#跳过列标题
;
我的%双向=();
while(我的$line=){
chomp$行;
我的($country1,$country2,$number1,$number2)=拆分“”,$line;
推送{$country1}{$country2},[$number1,$number2];
推送{$country2}{$country1},[$number1,$number2];
}
打印转储程序\%双向;
__资料__
国家1国家2数字1数字2
美国芝加哥美国洛杉矶12 14
澳大利亚悉尼美国芝加哥19 15
澳大利亚悉尼美国芝加哥22 21
奇奥香港RSA奇奥博格72 23
美国芝加哥93 27

这太棒了!非常感谢,我坐了3个小时就放弃了!感谢您的快速回复,因为井号
9327
的顺序相反。它应该是
2793
。请不要为键和值组合字符串。稍后您只需再次解析它们。请看我的回复。反馈很好,我改进了代码。谢谢
use strictures;
use Hash::MultiKey qw();

my @input = (
    'USA_Chicago USA_LA 12 14',
    'AUS_Sydney USA_Chicago 19 15',
    'AUS_Sydney USA_Chicago 22 21',
    'CHI_Hong-Kong RSA_Joburg 72 23',
    'USA_LA USA_Chicago 93 27'
);

tie my %hash, 'Hash::MultiKey';
for my $line (@input) {
    my ($c1, $c2, $n1, $n2) = split / [\s\|]+ /x, $line;
    my %map = ($c1 => $n1, $c2 => $n2);
    push @{ $hash{[sort keys %map]} }, @map{sort keys %map};

}
__END__
(
    ['CHI_Hong-Kong', 'RSA_Joburg'] => [72, 23],
    ['AUS_Sydney', 'USA_Chicago'] => [19, 15, 22, 21],
    ['USA_Chicago', 'USA_LA'] => [12, 14, 27, 93],
)
#!/usr/bin/env perl

use strict;
use warnings;

# --------------------------------------

use charnames qw( :full :short   );
use English   qw( -no_match_vars );  # Avoids regex performance penalty

use Data::Dumper;

# Make Data::Dumper pretty
$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Indent   = 1;

# Set maximum depth for Data::Dumper, zero means unlimited
local $Data::Dumper::Maxdepth = 0;

# conditional compile DEBUGging statements
# See http://lookatperl.blogspot.ca/2013/07/a-look-at-conditional-compiling-of.html
use constant DEBUG => $ENV{DEBUG};

# --------------------------------------

# skip the column headers
<DATA>;

my %bidirectional = ();

while( my $line = <DATA> ){
  chomp $line;

  my ( $country1, $country2, $number1, $number2 ) = split ' ', $line;

  push @{ $bidirectional{ $country1 }{ $country2 } }, [ $number1, $number2 ];
  push @{ $bidirectional{ $country2 }{ $country1 } }, [ $number1, $number2 ];

}

print Dumper \%bidirectional;


__DATA__
Country1        Country2           number1           number2
USA_Chicago     USA_LA             12                14
AUS_Sydney      USA_Chicago        19                15
AUS_Sydney      USA_Chicago        22                21
CHI_Hong-Kong   RSA_Joburg         72                23
USA_LA          USA_Chicago        93                27