in reply to •Re: Sort Multidimensional Hash By Multiple Columns
in thread Sort Multidimensional Hash By Multiple Columns
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;
Cheers - L~R
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^3: Sort Multidimensional Hash By Multiple Columns
by mdog (Pilgrim) on Aug 07, 2004 at 01:03 UTC |