Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Mysterious hash behaviour

by Anonymous Monk
on Apr 07, 2005 at 06:48 UTC ( [id://445554]=perlquestion: print w/replies, xml ) Need Help??

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

Hello Monks,
I have defined a hash and assigned values to it as follows:

my(%sortListArr); $sortListArr{'1'} = 'A1'; $sortListArr{'2'} = 'A2'; $sortListArr{'3'} = 'A3'; $sortListArr{'4'} = 'A4'; $sortListArr{'5'} = 'A5'; $sortListArr{'6'} = 'A6';

Then when I do a:

foreach $key (keys %sortListArr){ print $sortListArr{$key},"\n"; }

The o/p is A1, A2....A6. However upon adding a 7th value:

$sortListArr{'7'} = 'A7';

The o/p becomes A7, A1, A2, A3...A6. Any explanations to this mystery? The problem disappears if I assign the values as:

$sortListArr{'0'} = 'A1'; $sortListArr{'1'} = 'A2'; $sortListArr{'2'} = 'A3'; $sortListArr{'3'} = 'A4'; $sortListArr{'4'} = 'A5'; $sortListArr{'5'} = 'A6'; $sortListArr{'6'} = 'A7';

The o/p is then A1, A2.....A7.

Tamojit

20050407 Janitored by Corion: Added formatting

Replies are listed 'Best First'.
Re: Mysterious hash behaviour
by ysth (Canon) on Apr 07, 2005 at 06:57 UTC
    The order that things are returned by keys(), values(), or list-context %hash is not sorted in any particular way, and depends on how things happen to be stored in the hash. There are Tie modules on CPAN that will enable you to always get things back in a particular sorted order, or in insertion order, but only at the cost of slowing down all accesses to the hash. Usually if you want some particular order, you sort the returned keys:
    for $key (sort {$a <=> $b} keys %sortListArr) ...
    or
    for $key (sort {$sortListArr{$a} cmp $sortListArr{$b}} keys %sortListArr) ...
Re: Mysterious hash behaviour
by Zaxo (Archbishop) on Apr 07, 2005 at 06:57 UTC

    Hashes are not ordered. The list returned by keys does not preserve either insertion order or any ordering by value.

    With consecutive small numbers as keys, you can preserve order by using an array, instead.

    After Compline,
    Zaxo

Re: Mysterious hash behaviour
by borisz (Canon) on Apr 07, 2005 at 07:01 UTC
      sort keys %sortListArr works pretty good. Thanx:)
      borisz,
      I agree with you but feel you have left out some information that may result in misunderstandings. Insert order (which the modules you listed are good at) is often not the same as a desired sorted order. That is why I created Tie::Hash::Sorted. In this particular case, Tie::IxHash also can do naive sorts that meet the stated requirements but fail if gets any more complicated.

      Cheers - L~R

Re: Mysterious hash behaviour
by davido (Cardinal) on Apr 07, 2005 at 07:02 UTC

    Yes, the explanation is that hashes do not maintain order. You can not count on the keys being in any particular order, unless you sort them too. This is documented behavior.

    See perlintro: "Hashes have no particular internal order, though you can sort the keys and loop through them."


    Dave

      if the key is always an incremented integer, wouldn't an array be the appropriate data structure?

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-03-19 07:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found