Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Re: problem with hash keys

by btrott (Parson)
on Jun 17, 2001 at 07:13 UTC ( #89128=note: print w/ replies, xml ) Need Help??

in reply to problem with hash keys

Hashes do not preserve insertion order. In other words, it is simply a fluke that your examples #1 and #2 print out the hash keys in the correct order; they are the exception rather than the rule.

If you just want the keys sorted alphabetically, use

for my $k (sort keys %GRAMMAR) {
But you may run into situations where you really do want to preserve insertion order, and it's not just a matter of sorting alphabetically.

If you want to preserve insertion order and still use a hash, take a look at Tie::IxHash. Or, if you're not wedded to a hash, you could always use an array, and push array refs onto your list of grammars:

push @GRAMMAR, [ $1, $2 ];
And then when iterating:
for my $rec (@GRAMMAR) { print $rec->[0], "\n"; }
BTW, when you do a regex match w/ capturing parens, you really should check whether the regex successfully matches:
next unless /([A-Z]) -> (.*)/; $GRAMMAR{$1} = $2;
That way, if the regex fails--ie. the line you're looking at doesn't match that regex--you'll just skip that line. You don't want to use $1 and $2 if the match was unsuccessful, because there's no telling what they could contain. :)

Comment on Re: problem with hash keys
Select or Download Code
Replies are listed 'Best First'.
Re: Re: problem with hash keys
by june_bo (Novice) on Jun 17, 2001 at 07:25 UTC
    Thanks for all the good advice.
    I need to keep the order for cosmetic reasons; the user will expect to see the end results (a bunch of sets) in the same order he entered them.
    I have to use hashes because I do (what I think are) wonderful and amazing things with them later in the program.

    Thanks again to everyone.

      Then you can additionally store for each hash the order in which its keys are in:
      # ... push @grammar_keys, $1 unless exists $grammar{$1}; $grammar{$1} = $2; # ... print "$k\n" for my $k (@grammar_keys);
      (I've also taken the liberty of using lowercase variable names; you should probably use all-uppercase names only for special global variables).

      Or you can use a module like Tie::IxHash, which implements hashes with ordered keys just like you want.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://89128]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (8)
As of 2015-10-06 19:11 GMT
Find Nodes?
    Voting Booth?

    Does Humor Belong in Programming?

    Results (159 votes), past polls