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

Hi,

My code takes a few hash references, but as u all know, their order is different from wat u input( because they r deref-ed in their hash order ). What do I do to get them deref-ed in the same order as they were input..

diparun

Replies are listed 'Best First'.
Re: Sorting hash references
by davido (Cardinal) on Apr 24, 2004 at 20:55 UTC
    One possibility that I've considered using before is storing in your hash the insertion order.

    Consider the following code:

    my %hash; my $count = 0; while ( my $line = <DATA> ) { chomp $line; next unless $line; my ( $key, $value ) = split /\s*=\s*/, $line; $hash{$key} = { 'Order' => $count++, 'Value' => $value }; } my @ordered_keys = sort { $hash{$a}{Order} <=> $hash{$b}{Order} } keys %hash; print "$_ = $hash{$_}{Value}\n" for @ordered_keys; __DATA__ Bart = Simpsons Elane = Seinfeld Ross = Friends Oscar the Grouch = Sesame Street


    Dave

Re: Sorting hash references
by matija (Priest) on Apr 24, 2004 at 20:35 UTC
    You can't get the original order from a hash reference. That information is not preserved anywhere.

    However, if you control the code that calls your code, you might get them to us Tie::IxHash objects instead of ordinary hashrefs, and that does preserve the order.

Re: Sorting hash references
by blue_cowdawg (Monsignor) on Apr 24, 2004 at 20:56 UTC

        What do I do to get them deref-ed in the same order as they were input..

    quite a novel use of terminology there..

    To (I think) answer your question a hash by its very nature has no concept of "order of input" as you are looking for. However there is another way. Here is one approach:

    : : Much hand waving. : # initialize a couple of things my %asoc_ary=(); my @key_table=(); : : fanning the air some more sub putThingIn { my ($key,$value)=$_; push @key_table=$key; $asoc_ary{$key}=$value; } sub getThingsBack { foreach my $key(@key_table){ print $asco_ary{$key},$/; } }
    As you add things to the associative array %asco_ary you are keeping track of what order they were put there in the array @key_table. The function push adds things to an array to the end of the array which is the equivilant of saying $key_array[++$#key_array]="thing";.

    When you iterate through the key array and use those values as your keys into your associative array you will get your values back in the order you stored therm.

Re: Sorting hash references
by NetWallah (Canon) on Apr 25, 2004 at 04:28 UTC
    I think davido's approach is the cleanest/easiest. However, I would avoid the "sort" - since you are creating "@ordered_keys" anyway, why not store them in the right order as they are entered into the hash ?
    my %hash; my @ordered_keys; while ( my $line = <DATA> ) { chomp $line; next unless $line; my ( $key, $value ) = split /\s*=\s*/, $line; $hash{$key} = $value; push @ordered_keys, $key; } # No need to sort - @ordered_keys is already in the right sequence... print "$_ = $hash{$_}\n" for @ordered_keys;
    Of course, this begs the question - why use %hash at all - hopefully, you have a reason for that - need quick/random reference to the keys for an unstated reason.

    Offense, like beauty, is in the eye of the beholder, and a fantasy.
    By guaranteeing freedom of expression, the First Amendment also guarntees offense.