How can I extract hash values into an array in their insertion order?
Asked Answered
S

4

6

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);
Swound answered 3/8, 2010 at 13:13 Comment(1)
Initially, I had given the correct answer to @mb14, but the only democratic thing to do was to take it back and give it to Zaid, due to the high number of votes.Swound
C
17

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,...)
Cocci answered 3/8, 2010 at 13:49 Comment(0)
D
5

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.

Darkle answered 3/8, 2010 at 13:27 Comment(0)
P
3

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.

Pending answered 3/8, 2010 at 13:40 Comment(0)
A
2

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

Analog answered 3/8, 2010 at 13:19 Comment(3)
The documentation at 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.Swound
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 neededAnalog
The title of the question changed and so the question, so my answer is meaningless nowAnalog

© 2022 - 2024 — McMap. All rights reserved.