【问题标题】:Perl Hash of Hash哈希的 Perl 哈希
【发布时间】:2014-12-31 19:17:58
【问题描述】:

所以我尝试使用 Perl HoH 并将一些值从 HoH 推送到数组中。

这里有一部分代码可以更好的解释一下;

my $hoh = (
antenna_included=>{
    "1" => '1 MultiBand Antenna',
    "2" =>'2 Multiband Antennas',
    "3" =>'1 MultiBand Antenna & 2 WiFi Antennas',
    "4" =>'2 Multiband Cellular Antennas & 2 WiFi Antennas',
    "N" =>'No Antennas Included',
    },
ip_rating=>{
    I6 => 'IP 64',
    CD => 'Intrinsically Safe, Class 1 Div 2, IP 64',
    NI => 'No',
    });

foreach $group ( sort keys %hoh ) {
    foreach $spec ( sort keys %{ $hoh{$group} } ) {   
        print "$spec=>$hoh{$group}{$spec}\n";
    }

    print "what part is it: ";
    my $input = <STDIN>;
    chomp $input;

    if ( exists $hoh{$group} ) {
        print "$hoh{$spec}\n";                #this is the problematic line.  
    }
    else {
    print "not a match!\n";
    }
}

基本上,这个脚本的目标是遍历 HoH,但在每个散列块中它给出STDIN,然后你输入key,然后我想推那个value元素放入数组中。 (现在代码只是说print 用于调试)。

我试过了

$hoh{$group}{$spec}
$hoh{$group}
$hoh{$group}->{$spec}

对于$hoh{$group},我得到HASH(0x6ff920) 和所有其他值,它只是空白,没有错误。

有什么想法吗?谢谢

【问题讨论】:

    标签: perl hash-of-hashes


    【解决方案1】:

    使用-&gt; 运算符。

    HoH 下面的所有内容都是一个哈希ref,访问其中的元素需要-&gt; 运算符。 (从技术上讲,你有一个“hashref 的散列”而不是“hash 的散列”,因为这样的事情是不可能的。)

    有关参考的详细信息,请参阅perlref 文档。

    $hoh{$group}->{$spec}
    

    更新

    这是您的程序的修改版本。区别在于:

    • %hoh 的初始声明是使用散列变量 %hoh 完成的,而不是标量变量 $hoh。将初始化列表分配给$hoh 将导致列表的最后一个元素被分配给变量,在这种情况下,hashref 对应于ip_rating。这几乎肯定不是您想要的。
    • 尝试访问$hoh{$group} 的元素需要-&gt; 运算符,例如`$hoh{$group}->{$spec}。
    • 问题区域可能需要检查$hoh{$group}-&gt;{$input} 是否存在。如果它不存在,则输入无效,这就是消息所暗示的。

    你只需要了解hash和hashref的区别(类似于array和arrayref的区别)并意识到hash和array不能是其他hash或array的元素。 Hashrefs 和 arrayrefs 可以是其他数据结构的元素,因为只有标量可以包含在另一个数据结构中。散列和数组不是标量,但 references 是标量(包括 hashref、arrayrefs、coderefs 甚至 scalarrefs),是创建任何类型的复杂嵌套数据结构所必需的。


    my %hoh = (
        antenna_included=>{
            "1" => '1 MultiBand Antenna',
            "2" =>'2 Multiband Antennas',
            "3" =>'1 MultiBand Antenna & 2 WiFi Antennas',
            "4" =>'2 Multiband Cellular Antennas & 2 WiFi Antennas',
            "N" =>'No Antennas Included',
        },
        ip_rating=>{
            I6 => 'IP 64',
            CD => 'Intrinsically Safe, Class 1 Div 2, IP 64',
            NI => 'No',
        });
    
    foreach $group ( sort keys %hoh ) {
        foreach $spec ( sort keys %{ $hoh{$group} } ) {   
            print "$spec=>$hoh{$group}->{$spec}\n";
        }
    
        print "what part is it: ";
        my $input = <STDIN>;
        chomp $input;
    
        if ( exists $hoh{$group}->{$input} ) {
            print $hoh{$group}->{$input}."\n";
        }
        else {
            print "not a match!\n";
        }
    }
    

    【讨论】:

    • 感谢您的回复和参考。那没有用(至少只是将其添加到一个“有问题的”行中)。你认为可能是因为我需要在上面的for 循环上使用-&gt;operator,然后我才能引用它?
    【解决方案2】:

    大括号{...} 和括号(...) 非常不同。第一个定义了一个匿名散列,您可以将其分配给 scalar 变量,而第二个定义一个列表,您可以将其分配给 hash 变量。您将两者混合在一起,不清楚您的意思。

    • 如果你有一个标量变量$hoh,那么你需要用

      初始化它
      my $hoh = { ... }
      

      并使用间接运算符访问元素

      $hoh->{$group}->{$spec}
      

      $hoh->{$group}{$spec}
      
    • 如果你有一个 hash 变量,那么你需要用

      初始化它
      my %hoh = ( ... )
      

      直接访问元素

      $hoh{$group}->{$spec}
      

      $hoh{$group}{$spec}
      

    【讨论】:

    • @mojo: perl -E'%hoh = (G =&gt; {S =&gt; works}); ($group, $spec) = qw/G S/; say $hoh{$group}{$spec}'
    • 我的立场是正确的。我不明白为什么,如果$hoh={...},你不能$hoh{$key},但如果$hoh{$key} 返回一个hashref,你可以$hoh{$key}{$subkey} AND $hoh{$key}-&gt;{$subkey} 得到相同的结果。跨度>
    • @mojo:因为间接箭头是选项仅在一对右/左大括号}{ 或括号][ 之间。在任何情况下,否则将无法区分 $hoh{$key}%hoh 的元素和 $hoh-&gt;{$key}%$hoh 的元素。
    猜你喜欢
    • 2013-12-20
    • 2013-08-10
    • 1970-01-01
    • 2010-10-20
    • 2011-06-14
    • 2015-08-01
    • 2013-06-06
    • 2019-07-22
    相关资源
    最近更新 更多