【问题标题】:How can I iterate through nested hash of hash without knowing its key?如何在不知道其键的情况下遍历哈希的嵌套哈希?
【发布时间】:2019-09-08 16:11:39
【问题描述】:

我有一个哈希哈希,即我的数据结构中的哈希和哈希引用。当我只有主哈希名称而没有最深哈希的键时,我可以遍历最深哈希吗?

my %gates_info=(
    'order' => {
        'nand' => {
            'nand2_1' =>2,
            'nand2_5' =>-1,
            'nand2_4' =>2,
            'nand2_6' =>-1,
            'nand2_2' =>2,
            'nand2_3' =>3
        },
        'and' => {
            'and2'=>1,
            'and3'=>2,
        },
    }
);

sub max_gate_order {
    print values (%{$gates_info{'order'}});
    my @arr = (sort {$a <=> $b} values %{$gates_info{'order'}});
    return $arr[-1];
}

当我只有它的名称 %gates_info 并且没有诸如“nand”或“and”之类的键时,我想遍历整个哈希。我想要实现的是通过排序获得每个门中的最高数值。比如nand case中的3和and case中的2。 sub max_gate_order 用于排序和返回最大值。谢谢

【问题讨论】:

  • @SteffenUllrich;抱歉,我犯了一个错误并编辑了我的问题。请立即发表评论。
  • @Steffen Ullrich,只返回一个可能不是问题。我只是认为应该记录下来。

标签: perl cgi hash-of-hashes perl-hash hash-reference


【解决方案1】:

keys 会给你这些钥匙。

sub max_gate_order {
   my ($gates_info) = @_;
   my $max_order;
   my @gates;
   for my $gate_type (keys %{ $gates_info->{order} }) {
      for my $gate_id (keys %{ $gates_info->{order}{$gate_type} }) {
         my $order = $gates_info->{order}{$gate_type}{$gate_id};
         $max_order //= $order;
         if ($order >= $max_order) {
            if ($order > $max_order) {
               $max_order = $order;
               @gates = ();
            }

            push @gates, $gate_id;
         }
      }
   }

   return @gates;
}

my @gates = max_gate_order(\%gates_info);

上面返回所有具有最高顺序的门。

如果您需要门类型和门 id,请替换

push @gates, $gate_id;

push @gates, [ $gate_type, $gate_id ];

push @gates, [ $gate_type, $gate_id, $order ];

【讨论】:

    【解决方案2】:

    这是一个更长、更冗余的解决方案,实际上更像是一个练习。但是您可能会发现以这种方式检查哈希迭代的结构很有趣。 (我知道我知道!)如果您只有有主哈希名称 (%gates_info),并且没有任何键,这可能很有用。这就是您的问题所暗示的情况。这会拉出与哈希一样深的所有键和值名称,以防其中任何一个可能有用。我还上传了working example。 (请注意,这确实需要知道您的哈希有多少层。)

    #!/usr/bin/perl
    use strict;
    use warnings;
    use Data::Dumper;
    
    
    my %gates_info=(
        'order' => {
            'nand' => {
                'nand2_1' =>2,
                'nand2_5' =>-1,
                'nand2_4' =>2,
                'nand2_6' =>-1,
                'nand2_2' =>2,
                'nand2_3' =>3
            },
            'and' => {
                'and2'=>1,
                'and3'=>2,
            },
        }
    );
    print Dumper %gates_info;
    print "\n\n";
    
    my @gate;
    my $hival; 
    
    foreach my $gate (sort keys %gates_info) {
     foreach my $gatekey (sort keys %{$gates_info{$gate}}) {
       foreach my $deepkey (sort keys %{$gates_info{$gate}{$gatekey}}) {
       my $deepvalue = $gates_info{$gate}->{$gatekey}->{$deepkey};
    push @gate, $deepvalue;
    @gate = sort @gate;
    $hival = $gate[@gate - 1];
    print "Gate is $gate, gatekey is $gatekey, deepkey is $deepkey, deepvalue is $deepvalue\n"; 
      } 
    print "\nGatekey is $gatekey, highest value is $hival\n\n";
    @gate = (); #empty gate array
     } 
    }
    
    exit 0;
    

    代码的输出是:

    $VAR1 = 'order';
    $VAR2 = {
              'and' => {
                         'and2' => 1,
                         'and3' => 2
                       },
              'nand' => {
                          'nand2_3' => 3,
                          'nand2_6' => -1,
                          'nand2_4' => 2,
                          'nand2_5' => -1,
                          'nand2_2' => 2,
                          'nand2_1' => 2
                        }
            };
    
    
    Gate is order, gatekey is and, deepkey is and2, deepvalue is 1
    Gate is order, gatekey is and, deepkey is and3, deepvalue is 2
    
    Gatekey is and, highest value is 2
    
    Gate is order, gatekey is nand, deepkey is nand2_1, deepvalue is 2
    Gate is order, gatekey is nand, deepkey is nand2_2, deepvalue is 2
    Gate is order, gatekey is nand, deepkey is nand2_3, deepvalue is 3
    Gate is order, gatekey is nand, deepkey is nand2_4, deepvalue is 2
    Gate is order, gatekey is nand, deepkey is nand2_5, deepvalue is -1
    Gate is order, gatekey is nand, deepkey is nand2_6, deepvalue is -1
    
    Gatekey is nand, highest value is 3
    

    【讨论】:

      【解决方案3】:
      sub max_gate_order {
      
          my %hash =();
          foreach my $k (keys %{$gates_info{'order'}}) {
              my @arr = (sort {$a <=> $b} values %{$gates_info{'order'}->{$k}});
              $hash{$k} = $arr[-1];       
          }   
          return \%hash;
      
      }
      

      【讨论】:

      • 目前尚不清楚您首先要尝试实现什么,因为返回值与您在问题中想要的不同,并且您没有描述它应该做什么。此外,它无法处理任意深度嵌套散列,从您的问题来看,这对我来说似乎是一个要求,但也许不是。
      • @Steffen Ullrich,关于“此外,它无法处理任意深度嵌套哈希”,没有迹象表明这是必要的。恰恰相反,这似乎是不受欢迎的。
      • 您好,请解释一下为什么这是一个解决方案。谢谢
      • @d_kennetz;首先,我们使用keys函数来获取上述哈希的所有键,这些键是按顺序指向的。然后我们使用特定的键来获取其他散列的散列值,然后在同一行上使用 values 函数来获取最深散列的值。这些值是数字的,因此我们应用了排序函数,该函数按值对哈希进行排序。为了按升序排序,我们使用了 $a=>$b,特殊变量。如果我们需要降序,我们会使用 $b=>$a。所以我们得到了最深哈希中每个键的最高值,因此我们将它分配给一个哈希并返回它的引用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      • 2017-04-03
      • 1970-01-01
      • 1970-01-01
      • 2019-12-08
      • 1970-01-01
      相关资源
      最近更新 更多