Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

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
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.
    -tl

      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?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (12)
As of 2014-09-19 16:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (143 votes), past polls