【问题标题】:Printing multi keyed Hash in Perl在 Perl 中打印多键哈希
【发布时间】:2012-02-18 01:23:35
【问题描述】:

我有一个像这样索引的 perl 哈希:

my %hash;
$hash{'number'}{'even'} = [24, 44, 38, 36];
$hash{'number'}{'odd'} = [23, 43, 37, 35];

当我尝试像这样打印键名时:

foreach my $key (keys %hash{'number'})
{
   print "Key: $key\n";
}

我收到以下错误:

Type of arg 1 to keys must be hash (not hash slice) at test.pl

但是,当我将数组 ref 传递给函数并在那里打印时,它会打印值:

test(\%hash);

sub test
{
   my ($hash) = @_;
   foreach my $key (keys %{$hash->{'number'}})
   {
       print "Key: $key\n";     #outputs: even odd
   }
}

有人可以告诉我这里出了什么问题吗?另外,如果我有多键散列,在这种情况下,如果我这样做,散列由“数字”和“偶数”或“奇数”索引:

foreach my $key (keys %hash)
{
print "First Key: $key\n";  #Outputs number
}

那么我将始终将“数字”作为正确的输出,而我永远无法将“偶数”、“奇数”作为输出,对吗?这只是为了了解良好的编码习惯:)

这是完整的代码:

sub test
{
    my ($hash) = @_;
    foreach my $key (keys %{$hash->{'number'}})
    {
        print "Key: $key\n";
    }

}

my %hash;
$hash{'number'}{'even'} = [24, 44, 38, 36];
$hash{'number'}{'odd'} = [23, 43, 37, 35];

test(\%hash);

foreach my $key (keys %hash)
{
    print "First Key: $key\n";
}

foreach my $key (keys %hash{'number'})
{
  print "Key: $key\n";
}

谢谢, 新手

【问题讨论】:

    标签: perl


    【解决方案1】:
    my %hash;
    $hash{'number'}{'even'} = [24, 44, 38, 36];
    $hash{'number'}{'odd'} = [23, 43, 37, 35];
    

    %hash 是一个散列,其键是字符串 ('number'),其值是散列引用。

    foreach my $key (keys %hash{'number'})
    {
       print "Key: $key\n";
    }
    

    要引用属于%hash 的值,您需要编写$hash{'number'},而不是%hash{'number'}

    但是$hash{'number'} 是一个哈希引用,而不是一个哈希。要引用它所引用的哈希,您可以这样写:

    %{$hash{'number'}}
    

    把它们放在一起:

    my %hash;
    $hash{'number'}{'even'} = [24, 44, 38, 36];
    $hash{'number'}{'odd'} = [23, 43, 37, 35];
    
    foreach my $key (keys %{$hash{'number'}}) {
       print "Key: $key\n";
    }
    

    将产生这个输出:

    Key: even
    Key: odd
    

    (可能不是这个顺序)。

    【讨论】:

    • 而且,出于学术兴趣,这里有更多关于散列切片的信息,原始代码不小心做了什么:perldoc.perl.org/perldata.html#Slices
    • 天啊...就是这样!我在想全名是一把钥匙!感谢您的详细解释。它真的很有帮助:)
    • 如果您使用的是 5.14 或更高版本,键、值、each、push、pop、slice、shift 和 unshift 现在可以在引用上运行。这意味着keys %{ $hash{k} } 可以重写为keys $hash{k}。高兴!
    • @kbenson:只要我保证我的代码不需要在 5.14 之前的版本上运行,我就会很高兴使用它。 叹息
    【解决方案2】:

    你可以这样做:

    #!/usr/bin/perl -w
    use strict;
    use warnings;
    
    my %hash;
    $hash{'number'}{'even'} = [24, 44, 38, 36];
    $hash{'number'}{'odd'} = [23, 43, 37, 35];
    
    foreach my $i(keys %hash){
        print $i;
        foreach my $j(keys %{$hash{$i}}){
            print "\t".$j."\t";
            print join(" ",@{$hash{'number'}{$j}})."\n";
        }
    }
    

    【讨论】:

    • 是的,它成功了!非常感谢你。但是添加额外花括号的动机是什么?我的意思是 keys %{$hash{'number'}} worked but keys %hash{'number'}` 没有,这是为什么呢?
    • 请注意您自己的示例中的差异 - 在您传递给子例程的第二个示例中,这正是您正在做的。在第一个你不是。没有额外的大括号,它实际上不是一个哈希。
    猜你喜欢
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2017-09-30
    • 2016-12-18
    • 2014-10-18
    • 2012-08-10
    • 2012-10-23
    相关资源
    最近更新 更多