in reply to Array of hash sorting problem

#!/usr/bin/perl -l use strict; use warnings; my @aoh =( { 3 => 15, 4 => 8, 5 => 9, }, { 3 => 11, 4 => 25, 5 => 6, }, ... ); for my $h (@aoh) { my @keys_sorted_by_values = sort { $h->{$a} <=> $h->{$b} } keys %$ +h; print "{"; print " $_ => $h->{$_}," for @keys_sorted_by_values; print "},"; } __END__ { 4 => 8, 5 => 9, 3 => 15, }, { 5 => 6, 3 => 11, 4 => 25, }, ...

Note that this doesn't sort the original hashes' entries (in place), i.e. the order as returned by keys, values or each. The latter cannot be achieved this way because hashes have their own intrinsic ordering (appears pseudo-random), which is the result of the particular hashing function being used.  In other words, you cannot sort a hash itself, but only what you read from it, e.g. for printing out, or some other processing.

Replies are listed 'Best First'.
Re^2: Array of hash sorting problem
by murugaperumal (Sexton) on Mar 25, 2010 at 10:19 UTC
    foreach(@aoh) { my %a = %$_; my %c= reverse %a; foreach my $key (sort { $a <=> $b } keys%c) { print "$key=> $c{$key}\n"; } print "\n"; }
      foreach(@aoh) { my %a = %$_; my %c= reverse %a;

      The problem with reversing the hash is that if the values aren't unique, e.g.

      { 3 => 15, 4 => 8, 5 => 8, },

      you won't get the desired result...  So why impose unnecessary restrictions for no real gain?  For any reasonably sized hash, creating a reversed copy of it will approximately outweigh the benefits of not having to dereference in the sort function.

      Also, there's no need to create an extra temp hash %a, just write

      my %c = reverse %$_;
      Try this things.....
      foreach $hash ( @aoh) { my %new = reverse (%{$hash}); foreach ( sort {$a <=> $b } keys (%new )) { print " $new{$_} :$_ \n "; } print "-------------\n"; }