7

What would be the simplest method of sorting a list of variables according to the value they represent:

Let:

a = 5; b = 4; c = 3; d = 2; e = 1;
varList = {a, b, c, d, e};

Sort[varList]

Renders:

{1, 2, 3, 4, 5}

While my preferred output would be:

{e, d, c, b, a}

I expect the answer will be embarrassingly simple.

MathLind
  • 1,697
  • 1
  • 13
  • 22
  • Thanks for the accept. I saw your comment yesterday. I was not able to elaborate more. But try to do this step by step and if something is not clear I can explain those parts, ok? – Kuba Jan 11 '15 at 11:11
  • Ok, take a look at details for Part, 4th bullet point. It says that for expr[[{a,b,c}]] it will apply Head of expression for result. So I'm using something like Defer[{1,2,3}][[{1}, {3,2,1}]] to reorder things but preserve head Defer, it is done by {1}. Minimal example is: Hold[{1,2,3}][[ {1}, 1]], take a look what it evaluates to. – Kuba Jan 11 '15 at 11:34
  • Ahh! Crystal clear. Your minimal example did it. Thank you very much Kuba. Maybe you could squeeze in parts of this text in your answer. – MathLind Jan 11 '15 at 11:53

4 Answers4

14

Here's another way you might approach this kind of thing -- instead of assigning values to the variables using =, you can make them into rules. For example, here is a collection of "variable names" and values for those variables, and a rule to make the assignment explicit:

vars = {a, b, c, d, e};
vals = {5, 4, 3, 2, 1.1};
Thread[Rule[vars, vals]]

{a -> 5, b -> 4, c -> 3, d -> 2, e -> 1.1}

To get the output you want is now easy:

vars[[Ordering[vals]]]

{e, d, c, b, a}

(Thanks to Mike Honeychurch for the simplification!)

bill s
  • 68,936
  • 4
  • 101
  • 191
11

Unless you use := for varList definition. a,b... are lost. Here's more about that, in related Q&A: Generate list of strings from a list of assigned variables.

So:

a = 5; b = 4; c = 3; d = 2; e = 1;
varList := {a, b, c, d, e};

(Defer[varList] /. OwnValues[varList])[[{1}, Ordering[varList]]]
{e, d, c, b, a}
Kuba
  • 136,707
  • 13
  • 279
  • 740
8

As a followup to the answer by bill s, as of version 10, you should consider using Association instead of lists of rules. In this case, you could do the following:

Sort[AssociationThread[{a, b, c, d, e}, {5, 4, 3, 2, 1.1}]]

(* <|e -> 1.1, d -> 2, c -> 3, b -> 4, a -> 5|> *)

and then

Keys@%

(* {e, d, c, b, a} *)
Stefan R
  • 2,136
  • 18
  • 17
6

You could use Hold instead of List in varList:

a = 5; b = 4; c = 3; d = 2; e = 1;

varList = Hold[a, b, c, d, e];

SortBy[varList, # &]
(* Hold[e, d, c, b, a] *)
Simon Woods
  • 84,945
  • 8
  • 175
  • 324