我完全坚持一个问题:
我确实有一些庞大的perl脚本和几个巨大的多级hash_tables。 一切正常,但为了减少代码和可读性,我想将最后一个哈希引用交给一个子函数。
如前所述,我确实有几个不同的哈希表,例如 %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中有相同的“值”,但是具有不同的多级别: 具有2级密钥的hash_table2:
$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
答案 0 :(得分:1)
查看perlref
你应该只引用一个sub:
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";
}
答案 1 :(得分:0)
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} }
}
);
}
}
抱歉,没时间解释。
答案 2 :(得分:0)
sub print_all_values {
my %hash_tmp = shift @_;
printf $hash_tmp->{value1}.";";
printf $hash_tmp->{value2}.";";
printf $hash_tmp->{value3}."\n";
}
$hash_tmp->{value1}
引用了与%hash_tmp
完全分开的内容。将这些更改为$hash_tmp{value1}
可能会解决问题。此外,始终使用严格和警告。
答案 3 :(得分:0)
这应该可行,但我没有任何复杂的哈希来测试它。 :)
# --------------------------------------
# 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;
}