Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

Merging Arrays into a Hash with Substitutions

by svsingh (Priest)
on Apr 07, 2004 at 15:47 UTC ( #343311=perlquestion: print w/replies, xml ) Need Help??
svsingh has asked for the wisdom of the Perl Monks concerning the following question:

I have a script that queries a database and prints the results on an HTML page. Nothing special there. To start, I build my data structure by getting rows of data and putting them into a hash. I also have an array with all of the column headings in the query.

Originally, I merged the arrays into a hash with the following code:

while ( my @row = $dbQuery->fetchrow_array() ) { @info{@{$headings}} = @row; }

Then I realized that the null values in the table were raising undefined warnings. I fixed this by looking at each element in the row and replacing undefined values with empty strings. Here's the code:

while ( my @row = $dbQuery->fetchrow_array() ) { foreach (@{$headings}) { # replace nulls with empty strings if ( defined $row[0] ) { $info{$_} = shift @row; } else { $info{$_} = ""; } # if } # foreach } # while

I like the elegance of the former method, but it doesn't give me the data I want. The working code seems kludgy. Is there a way to get the results from the latter with the elegance of the former? How would you do this? Thank you.

Replies are listed 'Best First'.
Re: Merging Arrays into a Hash with Substitutions
by Enlil (Parson) on Apr 07, 2004 at 15:52 UTC
    Perhaps something like map might help.
    while ( my @row = $dbQuery->fetchrow_array() ) { @info{@{$headings}} = map { defined ? $_ : "" } @row; }


Re: Merging Arrays into a Hash with Substitutions
by broquaint (Abbot) on Apr 07, 2004 at 16:00 UTC
    A map should do it
    while ( my @row = $dbQuery->fetchrow_array() ) { @info{@$headings} = map { defined ? $_ : "" } @row; }
    Also, your null filling code is broken, because once a null is found the rest of the values are null because $row[0] doesn't change e.g
    my @r = (1, 2, undef, 3, 4); my %h; for(qw/abc def ghi jkl mno/) { if(defined $r[0]) { $h{$_} = shift @r; } else { $h{$_} = ""; } } print Dumper \%h; __output__ $VAR1 = { 'def' => 2, 'abc' => 1, 'mno' => '', 'jkl' => '', 'ghi' => '' };


Re: Merging Arrays into a Hash with Substitutions
by tilly (Archbishop) on Apr 07, 2004 at 16:22 UTC
    Taking a trick from TheDamian you could also do this:
    while ( my @row = $dbQuery->fetchrow_array() ) { $_ = "" for grep {not defined} @row; @info{@{$headings}} = @row; }
    (I'd probably still reach for map first.)
      Why have a grep and a for loop, though?
      # Grep in a void context! grep { defined or $_ = '' } @row; # or defined or $_ = '' for @row;
Re: Merging Arrays into a Hash with Substitutions
by graff (Chancellor) on Apr 09, 2004 at 04:19 UTC
    I realize that this is probably not the sort of thing you're looking for, but it's a handy thing to know about, and could help, if you are using SQL queries:

    You can specify in the query what to return for a given field when the row being returned happens to have a null in that field. I don't know whether this is the sort of thing where the syntax varies from one database system to the next, but in Oracle, you would do something like this:

    "select id,NVL(field_a,' '),NVL(field_b,'NO_B') from table..."
    The first arg to NVL() is a field to be returned, and the second arg is a string to be returned when the given field is null. It adds a bit of flexibility when doing queries, and can help simplify the perl scripting.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://343311]
Approved by matija
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (6)
As of 2017-06-26 20:07 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (590 votes). Check out past polls.