Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Returning a hash and looping on the results.

by Anonymous Monk
on Apr 18, 2014 at 14:21 UTC ( #1082766=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks!
I am trying to push the results of a db query into this hash, trying to return and loop through it to print the results, but I am stuck, might be a better way of doing it?
Here is code to show my problem:

my $result = data(); foreach my $key (keys %{ $result }) { my $value = $result->{$key}; print "User Name = $key - City: $value\n"; } sub data { ... db code stuff ... my %no_name_found; if(@$sql) { for(my $i = 0; $i < @$sql; $i++) { my $user_name = $sql->[$i]{'username'} || ''; my $city = $sql->[$i]{'city'} || ''; # verify user name, this name will come back from this sub check_ +name my $no_name = check_name ( user => $user_name, ); push @{ $no_name_found { $user_name } }, $city; } } return \%no_access_brks; }

Thanks for looking!

Replies are listed 'Best First'.
Re: Returning a hash and looping on the results.
by rnewsham (Curate) on Apr 18, 2014 at 14:30 UTC

    You return \%no_access_brks but that does not appear anywhere in the sub, did you intend to return \%no_name_found?

      It is not really clear what you are trying to achieve here. Your variable naming convention really does not make it clear what the desired output is.
      You do some undefined check on $user_name and put the results in $no_name which you do not use. You push the city value into an array but try to print as a scalar, perhaps a hash of arrays is not the appropriate data structure to use.

      Here is a slightly modified version of your code that uses a check_name sub and correctly displays the array contents. Hopefully this gives you a clue as to how to modify your code to achieve your goal.

      use strict; use warnings; my $result = data(); foreach my $key ( keys %$result ) { my $value = join(',', @{$result->{$key}}); print "User Name = $key - City: $value\n"; } sub data { #db code stuff my $sql = [ { username => 'abc', city=> 'foo' }, { username => 'def', city=> 'bar' }, { username => 'ghi', city=> 'goo' }, { username => 'jkl', city=> 'car' }, { username => 'm-n-o', city=> 'car' }, ]; #... my %no_name_found; if ( @$sql ) { for ( @$sql ) { my $user_name = $_->{'username'}; my $city = $_->{'city'} || ''; if ( check_name( $user_name ) ) { push @{ $no_name_found{ $user_name } }, $city; } } } return \%no_name_found; } sub check_name { my $name = shift; if ( $name =~ /^\w+$/ ) { return $name; } } Output User Name = def - City: bar,bas User Name = abc - City: foo User Name = jkl - City: car User Name = ghi - City: goo

      If you still are having problems please provide a more detailed description of what you are trying to achieve, include all relevant subs and a sample of input data and how you want it to display on output.

      Yes, I'm sorry!

        Problems like this can be avoided with the strict pragma. See Use strict warnings and diagnostics or die for a more thorough discussion.


        #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

        OK, this I found to be the better way of doing it:

        my $result = data(); foreach my $res (@$result) { my $name = $res->{'username'}; my $city = $res->{'city'}; print "User Name = $name - City: $city\n"; } my @all_data = (); sub data { ... db code stuff ... my %no_name_found; if(@$sql) { for(my $i = 0; $i < @$sql; $i++) { my $user_name = $sql->[$i]{'username'} || ''; my $city = $sql->[$i]{'city'} || ''; # verify user name, this name will come back from this sub check_ +name my $no_name = check_name ( user => $user_name, ); #Get a new hash for the data my %data; $data{username} = $user_name; $data{city} = $city; push @all_data, \%data; } } return \@all_data; }
Re: Returning a hash and looping on the results.
by kennethk (Abbot) on Apr 18, 2014 at 14:46 UTC
    push @{ $no_name_found { $user_name } }, $city;
    The value associated with the key is an array reference, and so
    my $value = $result->{$key}; print "User Name = $key - City: $value\n";
    will output something that looks like
    User Name = User - City: ARRAY(0x3eafa1c)
    You might get something closer to what you expect with
    my $value = $result->{$key}; local $" = ', '; print "User Name = $key - City: @$value\n";
    or
    my $value = $result->{$key}; print "User Name = $key - City: ", join(', ', @$value), "\n";
    or something similar.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1082766]
Approved by rnewsham
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2021-01-20 23:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?