Dcoder
Dcoder

Reputation: 379

Is it possible to make a iterate through a hash in perl in the order of how keys are stored?

Consider following hash :

my $hoh = {
'tag1' => {
    'name' => 'Item 1',
    'order' => '1',
    'enabled' => '1',
},
'tag2' => {
    'name' => 'Item 2',
    'order' => '2',
    'enabled' => '0',
},
'tag3' => {
    'name' => 'Item 3',
    'order' => '3',
    'enabled' => '1',
},

}

I am using following to get hash values :

for my $x (keys %{ $hoh{'tag1'} }) {
            my $y = $hoh{'tag1'}{$x};
            print "key is $x --- value is $y\n";
            }

But the output is not in the order the keys were stored! Is it possible to make sure the key value pairs are printed in order which they were stored ?

Upvotes: 3

Views: 110

Answers (3)

Miguel Prz
Miguel Prz

Reputation: 13792

Perl hashes don't store the order that you have used to define the hash. You can use the Tie::IxHash module.

I see that you have a hash of hashes, so you should use Tie::Hash for each hash you are using (if you want the sub-hashed in the same order), not only the $hoh hash, but also the nested hashes to each key.

use Tie::IxHash;
my %hoh = ();
tie %hoh, 'Tie::IxHash';

$hoh{'tag1'} = Tie::IxHash->new('name'=>'Item 1', 'order'=>'1', 'enabled'=>'1');
#...

Upvotes: 2

Richard Huxton
Richard Huxton

Reputation: 22893

There is no "order" in which the keys are stored. It's a hash. If you really want a specific order (for table headings etc) then keep a separate list.

my @table_headings = qw(name order enabled);
for my $k (@table_headings) {
    my $v = $hoh->{tag1}->{$k};
    print "$k => $v\n";
}

Upvotes: 2

mpapec
mpapec

Reputation: 50637

You'll need tied hash as plain hashes don't store it's keys in any particular order, http://perldoc.perl.org/functions/keys.html

use Tie::IxHash;
my $hoh = {};
tie %$hoh, 'Tie::IxHash';

%$hoh = (
  'tag1' => {
      'name' => 'Item 1',
      'order' => '1',
      'enabled' => '1',
  },
  'tag2' => {
      'name' => 'Item 2',
      'order' => '2',
      'enabled' => '0',
  },
  'tag3' => {
      'name' => 'Item 3',
      'order' => '3',
      'enabled' => '1',
  },
);

Upvotes: 1

Related Questions