Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当键和值都是数组引用时的Perl哈希_Perl_Hash_Reference - Fatal编程技术网

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

当键和值都是数组引用时的Perl哈希,perl,hash,reference,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(

我有一个问题,一对数字映射到另一对数字。例如,(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.

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

使用“二维”散列怎么样

与Perl中的大多数内容一样

选项1:使用多维数组模拟

$hash{$x,$y} = [$a, $b];
另请参见内置变量的文档

选项2:使用模块

tie %hash, 'Hash::MultiKey';
$hash{[$x, $y]} = [$a, $b];
选项3:改为使用HoH(散列)

$hash{$x}{$y} = [$a, $b];

我最终使用了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";

顺便说一句,我本想将此作为一个注释添加进来,但它太长了,我认为添加一个有效的示例是有意义的。

我最终使用了Socket Puppet的解决方案(以选项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";