in reply to Refactor my sort

Your question has already been well-answered. I am posting code for 5 methods, for variety and comparison.

  1. Your original code, placed in a sort sub (++jettero)-- Simple!
  2. Schwartzian Transform -- Fast!
  3. Guttman-Rosler Transform -- Faster!
  4. Sort::Maker -- Concise!
  5. Sort::Key -- Even more concise!

The simple sort sub is probably best for your needs. Fast enough, concise enough, and requiring no extra modules. The two transforms are included just as an illustration of how to write them yourself; they are more verbose than the simple sub, and you would only need their speed if you had many teams, or if your method calls were slow. Sort::Key and Sort::Maker are not core, but are almost as fast as the hand-coded transforms, and allow for very maintainable code. Sort::Maker is my favorite.

use strict; use warnings; # Heavily abused fake object class package Teams; sub get_wins_total { $_[0]->{ WT } } sub get_wins_division { $_[0]->{ WD } } sub get_wins_home { $_[0]->{ WH } } sub get_runs_scored { $_[0]->{ RS } } sub get_runs_allowed { $_[0]->{ RA } } sub get_reg_schedule_id { $_[0]->{ ID } } sub print_me { print map(sprintf("%7d\t", $_[0]->{$_}), qw( WT WD WH RS RA ID )), + "\n"; } package main; # Herkum's sort sub sub standings { $b->get_wins_total <=> $a->get_wins_total or $b->get_wins_division <=> $a->get_wins_division or $b->get_wins_home <=> $a->get_wins_home or $b->get_runs_scored <=> $a->get_runs_scored or $a->get_runs_allowed <=> $b->get_runs_allowed or $a->get_reg_schedule_id <=> $b->get_reg_schedule_id } # Schwartzian Transform sub sort_teams_by_standing_ST { return map { $_->[0] } sort { $b->[1] <=> $a->[1] or $b->[2] <=> $a->[2] or $b->[3] <=> $a->[3] or $b->[4] <=> $a->[4] or $a->[5] <=> $b->[5] or $a->[6] <=> $b->[6] } map {[ $_, $_->get_wins_total, $_->get_wins_division, $_->get_wins_home, $_->get_runs_scored, $_->get_runs_allowed, $_->get_reg_schedule_id, ]} @_; } # Guttman-Rosler Transform sub sort_teams_by_standing_GRT { return @_[ map { unpack 'x[l6] l', $_ } sort map { pack 'l7', -$_[$_]->get_wins_total, -$_[$_]->get_wins_division, -$_[$_]->get_wins_home, -$_[$_]->get_runs_scored, $_[$_]->get_runs_allowed, $_[$_]->get_reg_schedule_id, $_, } 0..$#_ ]; } # CPAN module Sort::Maker use Sort::Maker; sub sort_teams_by_standing_SM; make_sorter( name => 'sort_teams_by_standing_SM', qw( GRT ), number => [ qw( descending unsigned ), code => sub { $_->get_wins_ +total } ], number => [ qw( descending unsigned ), code => sub { $_->get_wins_ +division } ], number => [ qw( descending unsigned ), code => sub { $_->get_wins_ +home } ], number => [ qw( descending unsigned ), code => sub { $_->get_runs_ +scored } ], number => [ qw( ascending unsigned ), code => sub { $_->get_runs_ +allowed } ], number => [ qw( ascending unsigned ), code => sub { $_->get_reg_s +chedule_id } ], ) or die "make_sorter: $@"; # CPAN module Sort::Key use Sort::Key::Maker sort_teams_by_standing_SKM => sub { $_->get_wins_total, $_->get_wins_division, $_->get_wins_home, $_->get_runs_scored, $_->get_runs_allowed, $_->get_reg_schedule_id, }, qw( -integer -integer -integer -integer integer integer ); my @teams = map { bless $_, 'Teams' } ( { WT => 52, WD => 26, WH => 13, RS => 12, RA => 11, ID => 808 }, { WT => 52, WD => 27, WH => 16, RS => 200, RA => 100, ID => 909 }, { WT => 52, WD => 27, WH => 17, RS => 210, RA => 110, ID => 606 }, { WT => 52, WD => 27, WH => 17, RS => 210, RA => 111, ID => 303 }, ); print "\n"; $_->print_me for sort standings @teams; print "\n"; $_->print_me for sort_teams_by_standing_ST @teams; print "\n"; $_->print_me for sort_teams_by_standing_GRT @teams; print "\n"; $_->print_me for sort_teams_by_standing_SM @teams; print "\n"; $_->print_me for sort_teams_by_standing_SKM @teams; print "\n";

Replies are listed 'Best First'.
Re^2: Refactor my sort
by salva (Canon) on Dec 23, 2006 at 23:11 UTC
    Sort::Key and Sort::Maker are not core, but are almost as fast as the hand-coded transforms

    Actually, Sort::Key is faster than any other method. Only in some corner cases it could be surpassed by the GRT!

Re^2: Refactor my sort
by Herkum (Parson) on Dec 23, 2006 at 18:15 UTC
    That was a good bit of work and thorough; thanks a lot, I appreciate it. Cannot wait to try this at home...