Sorting AofH over hash key(s)...



I've searched this NG, the web, and CPAN and haven't seen anything to
do this, and while I have a solution, I'm wondering what other
solutions might be living inside some other pretty brilliant brain
cages here on c.l.p.m...

The problem seems fairly straight-forward: I want to be able to sort
an Array of Hashes by an arbitrary number of hash keys. For instance,
given this hash:

my $h = [
{ color => 'red', size => 1, width => 640, height => 480 },
{ color => 'blue', size => 4, width => 800, height => 600 },
{ color => 'green', size => 2, width => 1024, height => 768 },
{ color => 'orange', size => 5, width => 320, height => 280 },
{ color => 'purple', size => 3, width => 40, height => 50 },
];

I'd like to sort by the keys: color, size, width, and/or height. I
realize for only ONE hash key, I can do:

for my $info (sort { $a->{color} cmp $b->{color} } @{$h}) { blah() }
#...

But... What if I want to sort by say... color and then size? Or
height and then width? Or all the keys in some order? Again haven't
seen anything to do this. It's hard to imagine this has never been
solved, but then again, I've done a fair amount of Perl coding in my
day and I haven't run across the need to do this until recently.

My solution? Somewhat similar to a mod I saw on CPAN once that
flattened deep hashes into a dotted namespace. It was a serialization
(or a namespace transformation, more like it):

$h->{norman}->{width}-{arm}->{finger}->{pinky} = 1.5;

became:

$h{norman.width.arm.finger.pinky} = 1.5;

Or something like that. Anyway, my approach was to serialize the data
(not the keys) in the hashes in order of keys I wanted to sort on,
sort THAT array, and deserialize back in the right key order:

my $temp = [
'red\xFF1\xFF640\xFF480',
'blue\xFF4\xFF800\xFF600',
'green'\xFF2\xFF1024\xFF768',
'orange\xFF5\xFF320\xFF280',
'purple\xFF\xFF3\xFF40\xFF50',
];

my @sortedArray = sort @{$temp};

## Then deserialize in correct order...

Also, my example, with a lot of numeric data is somewhat bad, I
realize. I realize my solution doesn't sort numeric data properly
(due to ordinal values), but for the solution I needed it for,
immediately, the serialize -> sort -> deserialize method works for
now. The numeric/ordinal issue is one of the reasons I am asking
simply from a purist standpoint.

Anyone got something different/better? A mod to recommend that I am
not seeing on CPAN?

Thanks!
/usr/ceo

.



Relevant Pages

  • Re: Sorting AofH over hash key(s)...
    ... an Array of Hashes by an arbitrary number of hash keys. ... I'd like to sort by the keys: ... Also, my example, with a lot of numeric data is somewhat bad, I ...
    (comp.lang.perl.misc)
  • Sort on no less than sixteen keys
    ... have numeric data. ... The challenge I face is to sum the data per column in ... what I need is a sort on sixteen keys -because I need to be ... I know how to do the check, but I don't know how to do the sort. ...
    (microsoft.public.excel.programming)
  • Re: Ability to do numeric and alpha sort in one pass on data which is compirsed of both
    ... WD> I am attempting to sort data which has a combination of both numeric ... Now it would not be so bad, but the numeric data ... Trying to use core Perl verses adding ... you need to mung your keys ...
    (perl.beginners)
  • Re: I dig stumperings.....
    ... infinite impregnability where no-one's troubled by buses. ... suggesting both within and among the keys. ... but one went sort of like this. ...
    (talk.religion.buddhism)
  • Re: a question for sorting keys in Map
    ... I have a Map, actually a TreeMap, which will automatically sort the keys ... You can write your own Comparator object which implements the Compare ... strings so that X10 comes after X2 instead of before it. ... Unix ls command sort file names the way you want your strings to sort. ...
    (comp.lang.java.programmer)