Sorting list with variable

I want to sort (or sortby) the list. List contains uninitialized variable m and I can assume that m is a Natural number that is much larger then any constant.

Example input:

a = {-116*m, 0, 3 - 11*m, 1 - m, -20*m - 7, -m}


Example output:

{-116*m, -20*m - 7, 3 - 11*m, -m, 1 - m, 0}


My effort:

MAGICNUMBER = 1000000;
Sort[a, (#1 /. m -> MAGICNUMBER) < (#2 /. m -> MAGICNUMBER) &]

-
–  Mr.Wizard Oct 17 '12 at 0:05

2 Answers

Your own method seems fairly effective but it can be simplified:

a = {-116*m, 0, 3 - 11*m, 1 - m, -20*m - 7, -m};

SortBy[a, # /. m -> 1*^12 &]

{-116 m, -7 - 20 m, 3 - 11 m, -m, 1 - m, 0}

a[[ Ordering[a /. m -> 1*^12] ]]

{-116 m, -7 - 20 m, 3 - 11 m, -m, 1 - m, 0}


These methods will also perform much better than your use of Sort because the default sort algorithm is used rather than custom pairwise ordering.

-

For your example input, which happens to be a list with elements in which m appears up to linearly, you can simply do this:

lst = {-116*m, 0, 3 - 11*m, 1 - m, -20*m - 7, -m};
lst[[Ordering[D[lst, m]]]]
(*{-116 m, -7 - 20 m, 3 - 11 m, 1 - m, -m, 0}*)


which basically gets rid of each term that does not contain m, then orders the rest according to the coefficient of m.

If you have things like m^2 though this needs a bit more work.

-
'm' appears linearly, therefore it is possible to take derivative. However would that not mean that constant elements would be in random order? –  Margus Oct 17 '12 at 0:06
@Margus yes that's true, constant elements will remain in the order they are. –  acl Oct 17 '12 at 0:08
Well, then Sort[lst][[Ordering[D[Sort[lst], m]]]] would work. –  Margus Oct 17 '12 at 0:18
Yes that's much better than what I was coming up with. Is it OK if I add it to the answer (with credit)? –  acl Oct 17 '12 at 0:27