Search code examples
perlloopshashsubroutine

perl: subroutine returns 0 instead of specified array


I have a hash of hashes like this:

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

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

My subroutine is meant to search through the values of a specified key, e.g. search all 2s for e and return the value for key 1 in each case.

It works since it can print those things just fine, and I can also print it to a text file. I also want the same lines to be pushed to an array @output.

Why does my subroutine return zero which is saved in $hej in this case.

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;

output

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


Solution

  • There is no key "1" in first loop of your hash. Recursive subroutine is not a good choice here.

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

    Borodin's one line code is great. But we should search 2 s.

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

    As a summary, 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;
    

    And

    perl search_hash.pl
    cat data3.txt
    

    OUTPUT:

    Fred
    Homer
    George