go ahead... be a heretic PerlMonks

### Re: two order sort

by AnomalousMonk (Chancellor)
 on Mar 05, 2013 at 01:05 UTC ( #1021729=note: print w/replies, xml ) Need Help??

in reply to two order sort

Multi-key sort, both in descending order:

```>perl -wMstrict -le
"use List::Util qw(sum);
;;
my \$scan = {
a => [ 5, 6 ], b => [ 5, 10, 15 ], c => [ 100 ], d => [ 8, 9 ]
};
;;
my @sorted =
map  \$_->[0],
sort { \$b->[1] <=> \$a->[1]  or  \$b->[2] <=> \$a->[2] }
map  [ \$_,  scalar @{ \$scan->{\$_} },  sum @{ \$scan->{\$_} } ],
keys %\$scan
;
;;
print qq{@sorted};
"
b d a c

Replies are listed 'Best First'.
Re^2: two order sort
by LanX (Chancellor) on Mar 05, 2013 at 01:30 UTC
you forgot to tell that your (Schwarzian) approach is not only better readable but much faster, because the sums are only calculated once per entry. =)

Cheers Rolf

A decorate-sort-undecorate or GRT (Guttman-Rosler Transform) approach would be even faster, but I forgot how to decorate for descending sort. It's probably somewhere in A Fresh Look at Efficient Perl Sorting. Must look it up...

2. According to the Wikipedia article linked by LanX herein, "decorate-sort-undecorate" is just another term for "Schwartzian Transform".

I forgot how to decorate for descending sort.

Just negate the field(s). Unary minus ('-') for numeric and boolean not ('~') for alpha:

```# Ascending numeric and ascending alpha
print for map{
unpack 'x[Na4]a*', \$_
} sort map{
local \$^W;
pack 'Na4a*', (0+\$_), substr( \$_, 1), \$_
} @a;;
0cjlf
0dvys
0uvmu
1akkn
1imwi
1lpys
1pjzw
2uwep
3hiyn
3jrkx
3myrn
3ozcw
3rqhx
3vkon
6excm
7axqf
7lbhj
8klfd
9ijei
9klou

# Descending numeric and ascending alpha
print for map{
unpack 'x[Na4]a*', \$_
} sort map{
local \$^W; pack 'Na4a*', -(0+\$_), substr( \$_, 1), \$_
} @a;;
0cjlf
0dvys
0uvmu
9ijei
9klou
8klfd
7axqf
7lbhj
6excm
3hiyn
3jrkx
3myrn
3ozcw
3rqhx
3vkon
2uwep
1akkn
1imwi
1lpys
1pjzw

# Ascending numeric and descending alpha
print for map{
unpack 'x[Na4]a*', \$_
} sort map{
local \$^W;
pack 'Na4a*', (0+\$_), ~substr( \$_, 1), \$_
} @a;;
0uvmu
0dvys
0cjlf
1pjzw
1lpys
1imwi
1akkn
2uwep
3vkon
3rqhx
3ozcw
3myrn
3jrkx
3hiyn
6excm
7lbhj
7axqf
8klfd
9klou
9ijei

# Decending numeric and descending alpha
print for map{
unpack 'x[Na4]a*', \$_
} sort map{
local \$^W;
pack 'Na4a*', -(0+\$_), ~substr( \$_, 1), \$_
} @a;;
0uvmu
0dvys
0cjlf
9klou
9ijei
8klfd
7lbhj
7axqf
6excm
3vkon
3rqhx
3ozcw
3myrn
3jrkx
3hiyn
2uwep
1pjzw
1lpys
1imwi
1akkn

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

> A decorate-sort-undecorate or GRT approach would be even faster,

I'm confused, IMHO "Schwartzian Transform" and "Decorate-Sort-Undecorate" are two names of the same thing ... right ???

UPDATE: OK I got it. You were referring to GRT beeing faster. =)

Well in this case creating a float separating the two numeric values by a point should be fast enough.

Cheers Rolf

Thanks for the routine and the module (and the article - I'll have to read that). The code works great.

Create A New User
Node Status?
node history
Node Type: note [id://1021729]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2017-08-23 23:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Who is your favorite scientist and why?

Results (360 votes). Check out past polls.

Notices?