# Sorting a matrix except its last row

Given

M = {{"Utah", 2}, {"Iowa", 1}, {"Maine", 3}, {"Total", 6}}


I want to obtain the reverse-sorted result like this:

Reverse@SortBy[Most@M, Last]~Join~{Last@M}


giving

{{"Maine", 3}, {"Utah", 2}, {"Iowa", 1}, {"Total", 6}}


Still learning the languange, I kindly ask you to propose a shorter and - probably faster -solution for a country with 10^6 federal states.

-
Your code runs in my machine well under 1 sec for 10^6 elements- What is your expectation? – Dr. belisarius May 21 '14 at 0:11
M[[Ordering[M[[;; -2, 2]], All, Greater]]]~Join~(Last@M) should be faster. see Ordering – kglr May 21 '14 at 0:14
You can use RotateLeft instead of Most and Join but it's not affecting speed. RotateLeft@Reverse@SortBy[M, Last] & – Öskå May 21 '14 at 0:14
@kguler It's 6 times slower here – Dr. belisarius May 21 '14 at 0:17
@belisarius - as a novice I just wanted to know, if "I did the right way" - thanks for your quick reply. – eldo May 21 '14 at 0:17

Using belisarius's test setup and a modification of the Ordering-based method:

c = Transpose[{StringJoin /@ Permutations@Characters["123456789"], Range[9!]}];
M = Join[c, c, c];
ClearSystemCache[];
Print@Timing[l1=Reverse@SortBy[Most@M, Last]~Join~{Last@M};];
ClearSystemCache[];
Print@Timing[l2= M[[Ordering[M[[;; -2, 2]], All, Greater]]]~Join~{Last@M};];
ClearSystemCache[];
Print@Timing[l3=Reverse@M[[Ordering[Most[M[[All, 2]]]]]]~Join~{Last@M};];
ClearSystemCache[];
Print@Timing[l4 = Reverse@M[[Ordering[M[[;; -2, 2]]]]]~Join~{Last@M};]
ClearSystemCache[];
Print@ Timing[l5 = RotateLeft@Reverse@M[[Ordering[M[[All, 2]]]]];]
l1 == l2 == l3 == l4 == l5

(* {0.406250,Null}
{3.046875,Null}
{0.093750,Null}
{0.078125,Null}
{0.062500,Null}
True *)

-
Much faster (and correct result) now – Dr. belisarius May 21 '14 at 0:40