tags:

views:

112

answers:

4

Given a hash in Perl (any hash), how can I extract the values from that hash, in the order which they were added and put them in an array?

Example:

my %given = ( foo => '10', bar => '20', baz => '15' );

I want to get the following result:

my @givenValues = (10, 20, 15);
+2  A: 

You can use values , but I think you can't get them in the right order , as the order has been already lost when you created the hash

mb14
The documentation at http://perldoc.perl.org/functions/values.html agrees with you: The values are returned in an apparently random order. The actual random order is subject to change in future versions of Perl.
Tom
As long as Hash are not OrderedHash (as OrderedHash in ruby) the order is lost ...What you can do is store the list (foo, 10, bar, 20, 15) and convert it to an hash when needed
mb14
The title of the question changed and so the question, so my answer is meaningless now
mb14
+4  A: 

The following will do what you want:

my @orderedKeys = qw(foo bar baz);
my %records     = (foo => '10', bar => '20', baz => '15');

my @givenValues = map {$records{$_}} @orderedKeys;

NB: An even better solution is to use Tie::IxHash or Tie::Hash::Indexed to preserver insertion order.

dsm
+3  A: 

If you have a list of keys in the right order, you can use a hash slice:

 my @keys   = qw(foo bar baz);
 my %given  = {foo => '10', bar => '20', baz => '15'}
 my @values = @given{@keys};

Otherwise, use Tie::IxHash.

eugene y
+16  A: 

From perldoc perlfaq4: How can I make my hash remember the order I put elements into it?


Use the Tie::IxHash from CPAN.

use Tie::IxHash;
tie my %myhash, 'Tie::IxHash';

for (my $i=0; $i<20; $i++) {

    $myhash{$i} = 2*$i;
}

my @keys = keys %myhash;
# @keys = (0,1,2,3,...)
Zaid