Retrieving from a Hash in Insertion Order

Problem

The keys and each functions give you the hash elements in a strange order, and you want them in the order in which you inserted them.

Solution

Use the Tie::IxHash module.

use Tie::IxHash;
tie %HASH, "Tie::IxHash";
# manipulate %HASH
@keys = keys %HASH;         # @keys is in insertion order

Discussion

Tie::IxHash makes keys, each, and values return the hash elements in the order they were added. This often removes the need to preprocess the hash keys with a complex sort comparison or maintain a distinct array containing the keys in the order they were inserted into the hash.

Tie::IxHash also provides an object-oriented interface to splice, push , pop, shift, unshift, keys, values, and delete, among others.

Here’s an example, showing both keys and each:

# initialize
use Tie::IxHash;

tie %food_color, "Tie::IxHash";
$food_color{Banana} = "Yellow";
$food_color{Apple}  = "Green";
$food_color{Lemon}  = "Yellow";

print "In insertion order, the foods are:\n";
foreach $food (keys %food_color) {
    print "  $food\n";
}

print "Still in insertion order, the foods' colors are:\n";
while (( $food, $color ) = each %food_color ) {
    print "$food is colored $color.\n";
}


                  In insertion order, the foods are:
               
                    Banana
               
                    Apple
               
                    Lemon
               
                  Still in insertion order, the foods' colors are:
               
                  Banana is colored Yellow.
               
                  Apple is colored Green.
               
                  Lemon is colored Yellow.

See Also

The documentation for the CPAN module Tie::IxHash; Section 13.15

Get Perl Cookbook now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.