我有像这样的散列哈希:
my %HoH = (
flintstones => {
1 => "fred",
2 => "barney",
},
jetsons => {
1 => "george",
2 => "jane",
},
simpsons => {
1 => "homer",
2 => "marge",
},
);
我的子程序用于搜索指定键的值,例如搜索2
的所有e
,并在每种情况下返回密钥1
的值。
它可以工作,因为它可以很好地打印这些东西,我也可以将它打印到文本文件中。我也希望将相同的行推送到数组@output
。
为什么我的子程序返回零,在这种情况下保存在$hej
中。
sub search_hash {
# Arguments are
#
# $hash=hash ref
# $parameter1=key no. to search in
# $parameter2=value to find
# $parameter3=name of text file to write to
my ( $hash, $parameter1, $parameter2, $parameter3 ) = @_, ;
# Loop over the keys in the hash
foreach ( keys %{$hash} ) {
# Get the value for the current key
my $value = $hash->{$_};
my $value2 = $hash->{'1'};
search_hash( $value, $parameter1, $parameter2, $parameter3 );
for my $key ( $parameter1 ) {
my @output; #create array for loop outputs to be saved
if ( $value =~ $parameter2 ) {
push @output, "$value2"; #push lines to array
print "Value: $value\n";
print "Name: $value2\n";
open( my $fh, '>>', $parameter3 );
print $fh ( "$value2\n" );
close $fh;
}
return @output;
}
}
}
my $hej = search_hash( \%HoH, "2", 'e', 'data3.txt' );
print $hej;
不能使用字符串(" fred")作为HASH参考,而#34; strict refs"在使用中
答案 0 :(得分:1)
哈希的第一个循环中没有键“1”。递归子程序不是一个好选择。
my $value2 = $hash->{'1'};
Borodin的一行代码很棒。但我们应该搜索2秒。
在e中搜索所有2 s并在每种情况下返回键1的值。
总结一下,search_hash.pl
use strict;
use warnings;
use utf8;
my %HoH = (
Flintstones => { 1 => "Fred", 2 => "Barney" },
Jetsons => { 1 => "George", 2 => "Jane" },
Simpsons => { 1 => "Homer", 2 => "Marge" }
);
my @output2 = map { $_->{1} } grep { $_->{2} =~ /e/ } values %HoH;
open( my $fh, '>', "data3.txt");
print $fh ( "$_\n" ) foreach @output2;
close $fh;
并且
perl search_hash.pl
cat data3.txt
输出:
Fred
Homer
George
答案 1 :(得分:0)
子例程的返回表达式在与子例程本身相同的上下文中进行计算。由于您将子例程的结果假设为标量,因此在标量上下文中计算子例程,并在标量上下文中评估@output
。在标量上下文中,数组返回它包含的元素数。在这种情况下,@output
恰好为空,因此search_hash
返回零。
如果您想要@output
的元素而不是@output
中的元素数,则需要在列表上下文中调用子例程。将结果分配给数组是这样做的一种方式。
这是我在下面发布的重写中修复问题的方法。请注意,我将标量$hej
替换为下面的数组@hej
。
我还解决了其他问题。所有三个键中 1 的值 现在返回第二级哈希值,因为它们中的每一个都包含键 2 的值,其中包含 e (要查找的值)。见下文。
use strict;
use warnings;
my %HoH = (
Flintstones => { 1 => "Fred", 2 => "Barney" },
Jetsons => { 1 => "George", 2 => "Jane" },
Simpsons => { 1 => "Homer", 2 => "Marge" }
);
sub search_hash {
# Arguments:
# $hash: hash ref
# $search_key: key to search in each 2-nd level hash
# $search_string: value to find
my ( $hash, $search_key, $search_string ) = @_;
my @output;
foreach ( keys %{$hash} ) {
#print "Key: $_\n";
my $hash2 = $hash->{$_}; # 2-nd level hash (reference to)
my $search_val = $hash2->{$search_key}; # Value for key == parameter1
#print "Value: $search_val\n";
if ($search_val =~ /\Q$search_string/) {
my $id = $hash2->{'1'};
#print "Name: $id\n";
push @output, $id;
}
}
return @output;
}
my @hej = search_hash( \%HoH, '2', 'e' );
print "Result: @hej\n";