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

Dear Monks,

I've a situation here in which I have a hash with only 1 key which name I don't know......
Normally I use
foreach my $l (keys %$myHas) { .... }
to find the key.....
In this case I assume perl has better ways to do this ?

However it is also possible that I get a hash with more than 1 key. Also in this situation I'm only intrested in only 1 key (doesn't matter which one it is)

Any suggestion ?

Thanks in advance
Luca

Replies are listed 'Best First'.
Re: how to find a key from a hash
by Corion (Patriarch) on Nov 21, 2005 at 15:49 UTC

    You can always get at the first key and the first value of a hash by looking at the hash as a list:

    my ($key,$value) = %hash;

    If your hash has more than one key, you will get a key, but as a hash is not ordered, there is no guarantee that you will get a specific key.

      Or slice it out:

        my $key = (keys %hash)[0];

      • another intruder with the mooring in the heart of the Perl

Re: how to find a key from a hash
by Perl Mouse (Chaplain) on Nov 21, 2005 at 15:52 UTC
    my ($a_key) = keys %$myHas; foreach my $l (keys %$myHas) { .... last; } while (my ($a_key) = each %$myHas) { .... last; } keys %$myHas; # Reset iterator.
    Perl --((8:>*
Re: how to find a key from a hash
by jeffa (Bishop) on Nov 21, 2005 at 15:53 UTC

    You can always use grep if you know what the name will be like:

    use strict; use warnings; use Data::Dumper; my %hash = ( foo => 'bar', football => 'Monday', one_thing => 'another', ); my @match = grep /^foo/, keys %hash; print Dumper \@match;
    But why don't you know the name of the key? That's one of the major reasons to use a hash instead of a regular array (besides using them to find unique keys). Should you be using a regular array instead?

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: how to find a key from a hash
by sgifford (Prior) on Nov 21, 2005 at 16:31 UTC
    (keys %myHas)[0] is a very short way to say "give me the first key of this hash". It may not be fast if %myHas is very large, but it will be fine for just a few elements. You can replace 0 with another number to get a different hash key, or with a random number to choose one randomly. The keys are in no particular order, but will consistently be returned in the same order, so if you use (keys %myHas)[0] you don't know exactly which key that will return, but once it has returned a key it will keep returning that one as long as the hash isn't modified.
Re: how to find a key from a hash
by swampyankee (Parson) on Nov 21, 2005 at 15:54 UTC

    If there's one key in the hash, keys(%hash) will return a single element array (excuse me, I've gone into lecture mode...).

    If you really don't care about which key you get from a hash with more than one entry, wouldn't

    $key = shift(keys(%hash));
    ($key) = keys(%hash);

    be perfectly adequate?

    Incidentally, if there is going to be only one key in a hash or, if you've multiple keys and don't care which one you get, why are you using a hash?

    Thanks to Perl Mouse for pointing out a horrid error on my part; for some inane reason I thought shift(keys(%hash)) was valid Perl.

    emc

      wouldn't
      $key = shift(keys(%hash));
      be perfectly adequate?
      How could something that doesn't even have a remote chance of compiling be "perfectly adequate"?

      shift, but it's nature, must have an lvalue as its argument, and to be more precise, an lvalue that starts with an @. List context keys() is neither. shift isn't an alternative for [0].

      Perl --((8:>*

        Because I went into idiot mode; it tends to happen often on Mondays.

        emc

Re: how to find a key from a hash
by pileofrogs (Priest) on Nov 22, 2005 at 18:34 UTC
    If your question is about finding one key out of several, the only way I've done that is by building another hash with the value pointing toward the key. If you're doing this, you should consider making it a hash of lists, because while you can only have one value for each key, you can have multiple keys pointing to identical values, and turning a normal hash inside out like this can cause you to drop data if you don't store it in a list.

    If I can, I try to build both hashes simultainously.

    If I'm totally off my rocker, and this isn't a good way to handle the situation where you need to find one key out of several, I'd love to know more about it.

    Update:I'm a total loser. I re-read the original post and I just realised that this question wasn't about finding one key out of several... D'OH!