in reply to Sort options

#!/usr/bin/perl use warnings; use strict; my @list = qw(erez[11] dana[22] dana[0] erez[10] erez[1] erez[0] dana[ +10]); my @sorted = sort sorter @list; print join ' ', @sorted; sub sorter { my ($a_str, $a_num) = ($a =~ /(\w+).(\d+)/); my ($b_str, $b_num) = ($b =~ /(\w+).(\d+)/); return $a_str cmp $b_str unless $a_str eq $b_str; return $a_num cmp $b_num; }
Just a quick one. It would probably be more efficient to run the regexp match only once and transform the list items into somthing like ({str => 'dana', num => 10},...).

Replies are listed 'Best First'.
Re^2: Sort options
by broomduster (Priest) on Aug 03, 2008 at 16:54 UTC
    It would probably be more efficient to run the regexp match only once
    Maybe overkill here, but why not a Schwartzian?
    use strict; use warnings; my @split_list = qw( erez[11] dana[22] dana[0] erez[10] erez[1] erez[0] dana[10] ); print "Before: @split_list\n"; my @new_list = map { $_->[0] } sort { $a->[1][0] cmp $b->[1][0] or $a->[1][1] <=> $b->[1][1] } map { [ $_, [ (/(\w+).(\d+)/) ] ] } @split_list; print "After: @new_list\n";

    Before: erez[11] dana[22] dana[0] erez[10] erez[1] erez[0] dana[10] After: dana[0] dana[10] dana[22] erez[0] erez[1] erez[10] erez[11]
      Or a Guttman-Rossler, perhaps?

      use strict; use warnings; use List::Util q{max}; my @list = qw{ erez[11] arianne[2763] dana[22] bob[7] dana[0] erez[10] arianne[75] bob[37] erez[1] erez[0] bob[16] dana[10] }; my $longest = max map { length } map { m{(\w+)} } @list; my @sorted = map { substr $_, $longest + 4 } sort map { pack qq{A${longest}LA*}, m{(\w+)\[(\d+)}, $_ } @list; print qq{$_\n} for @sorted;

      produces

      arianne[75] arianne[2763] bob[7] bob[16] bob[37] dana[0] dana[10] dana[22] erez[0] erez[1] erez[10] erez[11]

      Cheers,

      JohnGG