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

wch*_*hlm 5 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] )
Run Code Online (Sandbox Code Playgroud)

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

$keyref = [ x1, y1 ]
$valref = [ a, b ]
%my_hash = { $keyref => $valref }
Run Code Online (Sandbox Code Playgroud)

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

有Perl解决方案吗?

谢谢,

-W.

soc*_*pet 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
Run Code Online (Sandbox Code Playgroud)


wch*_*hlm 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";
Run Code Online (Sandbox Code Playgroud)

PS 我本想将其添加为评论,但它太长了,我认为包含一个有效的示例是有意义的。