当键和值都是数组引用时,Perl哈希

时间:2011-10-26 05:44:32

标签: perl hash reference

我遇到一个问题,即数字对映射到其他数字对。例如,(1,2) - >(12,97)。有些对可以映射到多个其他对,所以我真正需要的是能够将一对映射到列表中,如(1,2) - >((12,97),(4,1))。在一天结束时,我想分别处理每个值(即每个列表列表)。

在Python中,我可以通过简单地说:

来做到这一点
key = ( x, y )
val = [ a, b ]
if (x,y) not in my_dict:
    my_dict[ (x,y) ] = []
my_dict[ (x,y) ].append( [a,b] )

然而,在Perl中,我必须使用refs作为键和值。所以我当然可以说:

$keyref = [ x1, y1 ]
$valref = [ a, b ]
%my_hash = { $keyref => $valref }

但是当另一对(x2,y2)出现时会发生什么?即使x2 == x1和y2 == y1,$ keyref = [x2,y2]也会与之前生成的keyref不同,所以我看不到进行查找的方法。当然,我可以将(x2,y2)与每个解除引用的哈希键进行比较,但毕竟,上帝精确地给了我们哈希表以避免需要这样做。

是否有Perl解决方案?

谢谢,

-W。

3 个答案:

答案 0 :(得分:10)

在Perl中,所有散列键都是字符串,或者在查找之前被“字符串化”。使用数组引用作为键通常是错误的方法。

使用“二维”哈希怎么样?

$hash{$x1}{$y1} = [ $a, $b ];
# or
%hash = ( $x1 => { $y1 => [ $a, $b ] } );


($x2,$y2)=($x1,$y1);
print @{$hash{$x2}{$y2}};   # will print $a and $b

答案 1 :(得分:2)

答案 2 :(得分:0)

我最终使用了Socket Puppet的解决方案(以Michael Carmen的选项3的形式)。仅供参考,这是一个小的Perl脚本,可以在我的应用程序中执行我需要的所有操作。

印刷线2:,3:和4:,5:只是使用不同的语法来做同样的事情,而第0行和第1行只是用来进行健全性检查。

这增加了建议的解决方案是使用数组数组作为与键一起使用的值。

@k1 = ( 12, 13 );
$aref = [ 11, 22 ];
$bref = [ 33, 44 ];
%h = {};
if( not exists $h{$k1[0]}{$k1[1]} ) {
    print "initializing\n";
    $h{$k1[0]}{$k1[1]} = [];
}
push @{$h{$k1[0]}{$k1[1]}}, $aref;
push @{$h{$k1[0]}{$k1[1]}}, $bref;
print "0: ", join ':', @{$h{$k1[0]}{$k1[1]}}, "\n";
print "1: ", join ':', ${$h{$k1[0]}{$k1[1]}}[0], "\n";
print "2: ", join ':', @{${$h{$k1[0]}{$k1[1]}}[0]}, "\n";
print "3: ", join ':', @{${$h{$k1[0]}{$k1[1]}}[1]}, "\n";
print "4: ", join ':', @{$h{$k1[0]}{$k1[1]}->[0]}, "\n";
print "5: ", join ':', @{$h{$k1[0]}{$k1[1]}->[1]}, "\n";

P.S。我会将此作为评论添加,但它太长了,我认为包含一个有效的例子是有意义的。