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

Sibling monks, I want to take a slice out of a hash %g by using an array of keys @cols. so I do my @vals = @g{@cols};. So far so good. BUT, I don't know what's in %g - it may have defined values for all fields, or it may not. What I want in @vals is the appropriate value from %g, or, if that value is not defined, I want some kind of placeholder, preferably undef but 0 or whatever wd be fine. I just need something, because when I've done my slicing I feed it to an SQL query thus:
my $placeholders = '?,' x @cols; chop $placeholders; my $cols = join ',', @cols; my $sth = $dbh->prepare("INSERT INTO venue ($cols) VALUES ($placeholde +rs)") or die $dbh->errstr; $sth->execute(@vals);
So my question is (A) can I force a hash slice to have an element for every key I feed it? or (B) is there some other cute way to do what I want? Thanks, all.

§ George Sherston

2001-12-11 Edit by Corion : Fixed a </CODE> tag

Replies are listed 'Best First'.
Re: Hash slice to get DB values - include undefined values?
by demerphq (Chancellor) on Dec 11, 2001 at 19:48 UTC
    Hi George_Sherston

    This already happens as the code below shows:

    my %hash=(a=>1,b=>2,c=>3); my @list=@hash{qw(a b c d e f)}; print "\t$_:",defined $list[$_] ? $list[$_] : "undef" foreach 0..$#lis +t; __END__ 0:1 1:2 2:3 3:undef 4:undef 5:undef
    Undef is returned as with any hash lookup where the key is undefined. BTW I wrote a module called Tie::Hash::Trie (which I have yet to upload anywhere, life got in the way :-) which amongst other things alows this to be changed to any arbitrary value. Let me know if you want to see.

    Yves / DeMerphq
    --
    This space for rent.

      Duh - how right you are... I thought that my problem was happening because my @vals array was too short... but, armed with the certainty that it couldn't be that, I revisit the code and find that it's another problem.

      The moral of this story is, if you want to know what's in an array in your CGI, don't do
      print @array;
      do
      print $_,br for @array;
      Thanks!

      § George Sherston
        Or perhaps
        print join("<BR>",@array)."<BR>";
        BTW, im sure you know this already but you could convert all of the undefs to a given constant quite easily
        my @values=map { exists $hash{$_} ? $hash{$_} : $constant } @keys_need +ed;
        You might want to change the exists() to a defined() if you dont want _any_ undefs getting through.

        :-)

        Yves / DeMerphq
        --
        This space for rent.

Re: Hash slice to get DB values - include undefined values?
by mortis (Pilgrim) on Dec 11, 2001 at 19:49 UTC
    I only know how to do what you're asking in 2 steps. I usualy do something similar to:
    $g{$_} ||= undef for @cols; my @vals = @g{@cols};
    I'd stick with undef since you're using a database. IIRC, undef translates to NULL to indicate the absence of a value, while 0 is a value.