merlyn,
I am likely wrong, but I don't see mdog's code being a reinvention of Sort::Fields. The code is designed to arbitrarily sort the keys of a multi-dimensional hash based off user supplied key names. It also sorts ascending or descending based off user input and auto-magically detects numerical versus ASCIIBetical sorting.
What mdog has provided is not very flexible. It assumes a specific structure. I was going to try and make it more generic, but gave up after only duplicating the fuctionality. Why you might ask - besides getting bored, look at the atrocity:
#!/usr/bin/perl
use strict;
use Tie::Hash::Sorted;
use Scalar::Util 'looks_like_number';
my @keys = qw(name number);
tie my %hash, 'Tie::Hash::Sorted';
@{ $hash{$_} }{ @keys } = ($_, '7.7') for qw(Me Chuck Zed);
@{ $hash{Wife} }{ @keys } = qw(Wife 7.6);
@{ $hash{Dad} }{ @keys } = qw(Dad 53);
@{ $hash{Michael} }{ @keys } = qw(Michael 24);
sub Build_Sort {
my $hash = shift;
my (@col , @ord);
$_ % 2 ? (push @ord , $_[$_]) : (push @col , $_[$_]) for 0 .. $#_;
my $sort_it = sub {
for ( 0 .. $#col ) {
if ( $ord[$_] eq 'dsc' ) {
if ( looks_like_number( $hash->{$a}{$col[$_]} ) && loo
+ks_like_number( $hash->{$b}{$col[$_]} ) ) {
next if ($hash->{$b}{$col[$_]} <=> $hash->{$a}{$co
+l[$_]}) == 0;
return $hash->{$b}{$col[$_]} <=> $hash->{$a}{$co
+l[$_]};
}
else {
next if ($hash->{$b}{$col[$_]} cmp $hash->{$a}{$co
+l[$_]}) == 0;
return $hash->{$b}{$col[$_]} cmp $hash->{$a}{$co
+l[$_]};
}
}
else {
if ( looks_like_number( $hash->{$a}{$col[$_]} ) && loo
+ks_like_number( $hash->{$b}{$col[$_]} ) ) {
next if ($hash->{$a}{$col[$_]} <=> $hash->{$b}{$co
+l[$_]}) == 0;
return $hash->{$a}{$col[$_]} <=> $hash->{$b}{$co
+l[$_]};
}
else {
next if ($hash->{$a}{$col[$_]} cmp $hash->{$b}{$co
+l[$_]}) == 0;
return $hash->{$a}{$col[$_]} cmp $hash->{$b}{$co
+l[$_]};
}
}
}
};
return sub {
my $h = shift;
[ sort $sort_it keys %$h ];
};
}
tied( %hash )->Sort_Routine( Build_Sort(\%hash, number => 'dsc', name
+=> 'asc') );
print "$hash{$_}{name}\t$hash{$_}{number}\n" for keys %hash;
|