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

Hi Monks,
I want print a hash orderly as I want, but the following code gave me unorder output, Any sugguestion on this , I'm a newbie here,so bear with me :)
--

my %grp_advise = ( "grp1" => "normal,random,sequential", "grp2" => "willneed,dontneed,free", "grp3" => "access_lwp,access_many,access_default" ); foreach my $grp (keys %grp_advise) { my $advise_value = $grp_advise{$grp}; print "$grp ===> $advise_value\n"; }

---output---

grp3 ===> access_lwp,access_many,access_default grp1 ===> normal,random,sequential grp2 ===> willneed,dontneed,free

20050525 Content restored by Corion

Replies are listed 'Best First'.
Re: hash unorderly output
by Nevtlathiel (Friar) on May 25, 2005 at 09:54 UTC
    foreach my $grp (sort keys %grp_advise) { #some stuff }

    Sort the keys of the hash and do whatever is in the foreach loop to each of them :)

    ----------
    My cow-orkers were talking in punctuation the other day. What disturbed me most was that I understood it.

Re: hash unorderly output
by muntfish (Chaplain) on May 25, 2005 at 09:57 UTC

    You don't say what order you want the data back in. If you want alphabetical order by key, that's easy:

    foreach my $grp (sort keys %grp_advise) { ...

    If you want them back in the order you added them, that's not possible with a perl hash. Or at least, it's substantially more difficult. ;-)


    s^^unp(;75N=&9I<V@`ack(u,^;s|\(.+\`|"$`$'\"$&\"\)"|ee;/m.+h/&&print$&
      Not conceptually that much more difficult, you just have to maintain an array and push the key to it every time you add a key to your hash, then to get the output in the order it went in something like:

      foreach my $key (@ordered) { ...

      ----------
      My cow-orkers were talking in punctuation the other day. What disturbed me most was that I understood it.

        Nevtlathiel,
        you just have to maintain an array and push the key to it every time you add a key

        It is actually a bit more complicated than that though none of the problems can't be overcome. If you delete a key you either need to splice out the corresponding array element or do an exists test when looping over the array. If you change a key's value should it then go to the end or stay put? I am not saying that it is isn't that simple in specific cases, but in general it is usually better to just use an already made wheel:

        Cheers - L~R

Re: hash unorderly output
by reasonablekeith (Deacon) on May 25, 2005 at 10:27 UTC
    or, as your 'key' seems just to be an index, why not just use an array?
    my @grp_advise = ( "normal,random,sequential", "willneed,dontneed,free", "access_lwp,access_many,access_default" ); for (my $grp_index = 0; $grp_index <= $#grp_advise; $grp_index++) { print "$grp_index ===> $grp_advise[$grp_index]\n"; }
    ---
    my name's not Keith, and I'm not reasonable.
Re: hash unorderly output
by Hena (Friar) on May 25, 2005 at 09:58 UTC
    # change foreach (keys %grp_advise) # into (sort keys %grp_advise)
    For some more information on sorting hashes, check out node 62697 from Q&A section.
Re: hash unorderly output
by davidrw (Prior) on May 25, 2005 at 15:17 UTC
    I think that the OP might be expecting that keys %grp_advice always return ("grp1","grp2","grp3") in that order because that is how the hash was declared, but it will not. From perldoc -f keys section of perlfunc:
    keys HASH
      Returns a list consisting of all the keys of the named hash. (In
      scalar context, returns the number of keys.) The keys are
      returned in an apparently random order. The actual random order
      is subject to change in future versions of perl, but it is
      guaranteed to be the same order as either the "values" or "each"
      function produces (given that the hash has not been modified).
      As a side effect, it resets HASH's iterator.
    
Re: hash unorderly output
by chanakya (Friar) on May 26, 2005 at 06:25 UTC
    The following code snippet should help you
    use strict; use warnings; use Tie::IxHash; tie my %hash_var, 'Tie::IxHash'; %hash_var = ( "grp1" => "normal,random,sequential", "grp2" => "willneed,dontneed,free", "grp3" => "access_lwp,access_many,access_default" ); #Print the hash foreach my $grp (keys %hash_var) { my $advise_value = $hash_var{$grp}; print "$grp ===> $advise_value\n"; }
    Hope this helps

    !!@!!
    May the force be with you
Re: hash unorderly output
by Amar (Sexton) on May 26, 2005 at 04:42 UTC