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

I have a hash of hashes and I want to list the inner hashes $names in the order they've been entered into the hash. I know I can't use "keys" but I use keys to get the number of items with the following two lines of code ...

@myArea = sort (keys %{$camArray{$trafficArea}}); $items = scalar @myArea;

Then, I can use a "for" loop to print out each name ...

for ($i=0; $i < $items; $i++) { print "\t<option>$myArea[$i]\n"; }

but this of course uses the keys sort. So I've been trying to do something along the lines of ...

for ($j=0; $j < $items; $j++) { print "$camArray{$trafficArea}{$j}\n"; }

to get at the values in order, all to no avail. Is there a way to get at the entries in a hash in order? Here is the hash of hashes I'm using ...

%camArray = ( 'seattle' => { ' Select a Traffic Cam' => '', 'I-5 at NE 45th St' => 'cctv135', 'I-5 at Roanoke St' => 'cctv126', 'I-5 at Yesler Way' => 'cctv105', 'I-5/I-90 Interchange' => 'cctv812', 'I-5 at Holgate St' => 'cctv098', 'I-5 at Spokane St' => 'cctv093', 'I-5 at Albro Place' => 'cctv086', 'I-5 at Mid Boeing Field' => 'cctv081', 'I-90 at 18th Ave. S.' => 'cctv821', 'I-90 Midspan' => 'cctv859', 'Hwy 520 at Montlake' => 'cctv504', 'Hwy 520 Midspan' => 'cctv509', 'Hwy 99 at Michigan St' => 'cctv498', 'Hwy 99 at W Marginal Way' => 'cctv497' }, 'tacoma' => { ' Select a Traffic Cam' => '', 'Narrows Bridge - westside' => '016cc0085', 'Narrows Bridge - eastside' => '016cc0047', 'I-5 south of Tacoma' => 'TacSouth', 'I-5 north of Tacoma' => 'TacNorth', 'I-5/Hwy 16 Interchange' => '005cc1324', 'I-5 at S. 48th Street' => '005cc1312', 'Hwy 16 at Center St.' => '016cc0019', 'Hwy 16 at Pearl St.' => '016cc0037' }, );

Thanks for any help!

rHOnDO

Replies are listed 'Best First'.
Re: Accessing a hash of hashes in order ...
by maverick (Curate) on Aug 08, 2001 at 02:48 UTC
    perhaps you'd be better off changing your data structure to look like
    %camArray = ( 'seattle' => [ [ ' Select a Traffice Cam', '' ], [ 'I-5 at NE 45th St', 'cctv135' ], . . .
    Then you could get them out in the order you put them in. You'd access it like
    foreach (@{$camArray{$trafficArea}}) { print "$_->[0]\n"; # for the label print "$_->[1]\n"; # for the value }

    /\/\averick

Re: Accessing a hash of hashes in order ...
by runrig (Abbot) on Aug 08, 2001 at 02:31 UTC
    Well, you could used a tied hash. See perldoc perltie. See Tie::SortHash for an example of something similar to what you want to do. I could have sworn there was already a module to do this, but I could be mistaken.
    Or consider using an array ref to keep the keys ordered, with a separate hash ref for looking up the values.
    Or use a fixed-length numeric prefix on all your keys for sorting, and strip it off when displaying, etc.

    Update:++Hofmator! I did a CPAN search on both 'Hash' and 'Tie' looking for something familiar, but overlooked Tie::IxHash somehow. Also, I'll have to crack open my Cookbook again in the near future :-)

      I could have sworn there was already a module to do this, but I could be mistaken.
      Maybe you were thinking of Tie::IxHash to receive the keys in the order the elements were inserted into the hash. From the Cookbook (recipe 5.6):
      use Tie::IxHash; tie %HASH, "Tie::IxHash"; # manipulate %HASH @keys = keys %HASH; # @keys is in insertion order

      -- Hofmator