【问题标题】:How to handover multilevel hashtable in perl如何在 perl 中切换多级哈希表
【发布时间】:2013-07-15 00:05:08
【问题描述】:

我完全陷入了一个问题:

我确实有一些巨大的 perl 脚本,其中包含几个巨大的多级哈希表。 一切正常,但为了减少代码和可读性,我想将最后一个哈希引用交给子函数。

如前所述,我确实有几个不同的哈希表,例如 %hash_table1 和 %hash_table2 都具有相同的值,但键的级别不同。

具有 3 级键的 hash_table1:

$hash_table1{$key1}{$key2}{$key3}->{value1}
$hash_table1{$key1}{$key2}{$key3}->{value2}
$hash_table1{$key1}{$key2}{$key3}->{value3}

我在另一个 hash_table 中确实有相同的“值”,但具有不同的多级: hash_table2 具有 2 级键:

$hash_table2{$key1}{$key2}->{value1}
$hash_table2{$key1}{$key2}->{value2}
$hash_table2{$key1}{$key2}->{value3}

我可以轻松地通过复制所有代码来分别访问所有值,更改其中的键数量,但大多数时候,我确实有 20 个不同的值,所以......访问数据的代码量是……嗯……很大。此外,如果需要更改某些内容,我将不得不多次更改;(

我想要的是类似于以下子函数的东西,我基本上只是将最后一个哈希键引用存储在一个临时哈希表中,以便以相同的方式轻松访问不同哈希表的所有值(这是部分这不起作用!!!):

sub print_all_values {
    my %hash_tmp = shift @_;
    printf $hash_tmp->{value1}.";";
    printf $hash_tmp->{value2}.";";
    printf $hash_tmp->{value3}."\n";
}

在代码中的某处,我通过多级处理,并将最后一个引用传递给前一个定义的子函数来做......好吧,应该用存储的值做什么(比如说打印):

foreach my $k1 (sort {$a <=> $b} keys %hash_table1){
   foreach my $k2 (sort {$a <=> $b} keys %{$hash_table1{$k1}}){
      foreach my $k3 (sort {$a <=> $b} keys %{$hash_table1{$k1}{$k2}}
         print_all_values(%{$hash_table1{$k1}{$k2}{$k3}});
      }
   }
}

在其他地方结束访问二级hash_table的代码:

foreach my $k1 (sort {$a <=> $b} keys %hash_table2){
   foreach my $k2 (sort {$a <=> $b} keys %{$hash_table2{$k1}}){
      print_all_values(%{$hash_table2{$k1}{$k2}});
   }
}

如前所述,最好有一个可行的解决方案将最后一个哈希引用传递给子函数,以便基本上一次访问所有存储的值。

非常感谢任何有用的评论,

一切顺利,

OldMcFunsy

【问题讨论】:

  • 哇!这让我的大脑很受伤。这个解决方案急需Object Oriented approach。这将有助于保持所有哈希键同步。给我更多关于各种键代表什么的信息,我也许可以快速找到答案。面向对象将帮助您处理这些乱七八糟的键和散列级别,并使您的代码更加简洁和易于维护。
  • %hash_tmp$hash_tmp-&gt;{key} 指的不是同一个哈希!

标签: perl hashtable


【解决方案1】:

看看perlref

你应该只传递一个对子的引用:

print_all_values(\%hash_table);

sub print_all_values {
    my $hash_tmp = shift;
    printf $hash_tmp->{value1}.";";
    printf $hash_tmp->{value2}.";";
    printf $hash_tmp->{value3}."\n";
}

【讨论】:

  • 非常感谢,我从来没有想过将我的 hash_tmp 声明为参考而不是 hash_table。刚刚从 % 更改为 $。你无法想象我花了多少时间来尝试这段代码。非常感谢!!!
【解决方案2】:
sub print_all_values {
    print(join(";", @_), "\n");
}

for my $k1 (sort {$a <=> $b} keys %hash_table1) {
   for my $k2 (sort {$a <=> $b} keys %{ $hash_table1{$k1} }) {
      print_all_values(
         @{ $hash_table1{$k1}{$k2} }{
            sort {$a <=> $b} keys %{ $hash_table1{$k1}{$k2} }
         }
      );
   }
}

抱歉,没时间解释了。

【讨论】:

  • 您好,谢谢你们,两种解决方案都有效并满足了我的要求。你无法想象我花了多少时间来解决这个问题!!!
【解决方案3】:
sub print_all_values {
    my %hash_tmp = shift @_;
    printf $hash_tmp->{value1}.";";
    printf $hash_tmp->{value2}.";";
    printf $hash_tmp->{value3}."\n";
}

$hash_tmp-&gt;{value1} 引用了与%hash_tmp 完全不同的东西。将这些更改为$hash_tmp{value1} 可能会解决此问题。此外,请始终使用严格和警告。

【讨论】:

    【解决方案4】:

    这应该可以,但我没有任何复杂的哈希值来测试它。 :)

    # --------------------------------------
    #       Name: scan_hash
    #      Usage: %value_of = scan_hash( \%hash_tree, @keys );
    #    Purpose: To do a depth first scan of the hash tree
    #             and create a hash of the leaves.
    # Parameters: \%hash_tree -- Tree to scan
    #                   @keys -- List of keys; these may appear anywhere in the tree
    #    Returns:   %value_of -- a simple key=>value has,
    #                            the keys are from @keys
    #                            and their values are what was found
    #
    sub scan_hash {
      my $hash_tree = shift @_;
      my @keys      = @_;
      my %value_of  = ();
    
      for my $key ( keys %$hash_tree ){
    
        # save if the current key is one we're looking for
        if( grep { $_ eq $key } @keys ){
          $value_of{$key} = $hash_tree->{$key};
    
        # is it a reference?
        }elsif( my $ref = ref( $hash_tree->{$key} )){
    
          if( $ref eq 'HASH' ){
    
            # hash references are scanned via recursion
            my %new_value_of = scan_hash( $hash_tree->{$key}, @keys );
    
            # stored using slices: http://perldoc.perl.org/perldata.html#Slices
            @value_of{ keys %new_value_of } = values %new_value_of;
    
          }else{
            die "cannot handle a $ref reference\n";
          }
    
        } # end if
    
      } # end for
    
      return %value_of;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-22
      • 2013-08-10
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      • 2014-10-18
      • 2023-04-07
      • 2010-09-16
      相关资源
      最近更新 更多