7
$\begingroup$

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.

$\endgroup$
3
  • $\begingroup$ 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? $\endgroup$
    – Kuba
    Jan 11, 2015 at 11:11
  • $\begingroup$ 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. $\endgroup$
    – Kuba
    Jan 11, 2015 at 11:34
  • $\begingroup$ 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. $\endgroup$
    – MathLind
    Jan 11, 2015 at 11:53

4 Answers 4

11
$\begingroup$

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}
$\endgroup$
0
14
$\begingroup$

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!)

$\endgroup$
2
  • $\begingroup$ I was going to suggest this...glad I read the responses first for a change. (Always easier to upvote than to code.) $\endgroup$ Jan 6, 2015 at 21:15
  • $\begingroup$ or just Thread[Rule[vars, vals]] $\endgroup$ Jan 6, 2015 at 21:46
8
$\begingroup$

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} *)
$\endgroup$
6
$\begingroup$

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] *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.