Re: Sorting AofH over hash key(s)...



On Oct 30, 4:40 pm, "/usr/ceo" <news...@xxxxxxx> wrote:
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.

# from the Perl Cookbook

my @sorted =
sort { $a->name cmp $b->name
||
$b->age <=> $a->age } @employees;


.



Relevant Pages

  • 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: How can I Sort hash in numeric context
    ... hashes don't work like this in Perl or in most other languages. ... perldoc -f sort and perldoc -f keys for some hints. ... you'll have to ask the hash for its keys and sort the keys. ... If you'd like to maintain the order of hash keys, you can keep a sorted copy ...
    (comp.lang.perl.misc)
  • 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)
  • Re: sorting DBM hash
    ... a DBM Hash. ... The first sort routine prints out keys and value. ... An anonymous sub routine is used to hold sub routines ...
    (perl.beginners)
  • Re: Mergesort Vs Quicksort
    ... sort and quick sort are the same, ... but this month with the particular sequence of time reports ... keys which are not contiguous but instead split into multiple fields; ... my algorithms are progressively faster but use ...
    (comp.programming)