perl: 子程序 returns 0 而不是指定的数组

perl: subroutine returns 0 instead of specified array

我有这样的哈希:

my %HoH = (
    flintstones => {
        1 => "fred",
        2 => "barney",
    },
    jetsons => {
        1 => "george",
        2 => "jane",

    },
    simpsons => {
        1 => "homer",
        2 => "marge",
    },
);

我的子例程旨在搜索指定键的值,例如在所有 2 中搜索 e 和 return 键值 1 在每种情况下。

它的工作原理是因为它可以很好地打印这些东西,而且我还可以将它打印到文本文件中。我还希望将相同的行推送到数组 @output.

在这种情况下,为什么保存在$hej中的子程序return为零。

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;

输出

Can't use string ("fred") as a HASH ref while "strict refs" in use

子例程的 return 表达式在与子例程本身相同的上下文中求值。由于您假设子例程的结果为标量,因此子例程在标量上下文中求值,而 @output 在标量上下文中求值。在标量上下文中,数组 returns 它包含的元素数。在这种情况下,@output 恰好为空,因此 search_hash return 为零。

如果您想要 @output 的元素而不是 @output 中的元素数量,则需要在列表上下文中调用子例程。将结果分配给数组是一种方法。

这就是我在下面发布的重写中解决问题的方法。请注意,我用下面的数组 @hej 替换了标量 $hej

我还解决了其他问题。这三个键的值 1 二级哈希现在被 returned,因为它们中的每一个都包含一个键 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";

您的散列的第一个循环中没有键“1”。递归子程序在这里不是一个好的选择。

my $value2 = $hash->{'1'};

Borodin 的一行代码很棒。但是我们应该搜索2秒。

search all 2 s for e and return the value for key 1 in each case.

总而言之,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