【问题标题】:Perl hash when both the keys and the values are array references当键和值都是数组引用时的 Perl 哈希
【发布时间】:2011-12-15 11:48:21
【问题描述】:

我遇到了一个问题,即成对的数字映射到其他成对的数字。例如,(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.

【问题讨论】:

  • 您不能使用引用作为键。 (至少不使用 tied 哈希)

标签: perl hash reference


【解决方案1】:

在 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

【讨论】:

    【解决方案2】:

    和 Perl 中的大多数东西一样,TMTOWTDI

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

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

    另请参阅内置变量 $; 的文档。

    选项 2:使用 Hash::MultiKey 模块

    tie %hash, 'Hash::MultiKey';
    $hash{[$x, $y]} = [$a, $b];
    

    选项 3:改用 HoH(哈希散列)

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

    【讨论】:

    • 我最终使用了 Socket Puppet 的解决方案(以您的选项 3 的形式)。仅供参考,这是一个小 Perl 脚本,它执行我需要在我的应用程序中执行的所有操作。打印的第 2:,3: 和 4:,5: 行只是使用不同的语法来做同样的事情,而 0: 和 1: 只是作为一路上的健全性检查。唯一添加到这些示例中的是使用数组数组作为键的值。
    【解决方案3】:

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

    附:我会将此添加为评论,但它太长了,我认为包含一个有效的示例是有意义的。

    【讨论】:

    • 祝贺解决方案。如果有能力,请确保将您的答案标记为“已接受”,以便其他人可以从您的成功中学习。干杯~
    猜你喜欢
    • 2016-06-06
    • 2011-12-29
    • 1970-01-01
    • 2014-07-23
    • 2014-01-04
    • 2012-09-21
    • 2011-07-26
    • 1970-01-01
    • 2012-06-09
    相关资源
    最近更新 更多