U
/usr/ceo
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
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