Sort lists according to the order of another

You can use combination of Part and Ordering as

list1[[ Ordering @ list2 ]]

to sort list1 in the order of list2.

Examples:

{list1, list2, list3} = {{1, 3, 2}, {a, b, c}, {x, y, z}};
list2[[ Ordering @ list1 ]]

gives

{a, c, b}

and

list3[[ Ordering @ list1 ]]

gives

{x, z, y}

EDIT: Using with lists of lists, to sort the entire array based on the first list:

list = {list1, list2, list3};
list[[ All, Ordering @ list[[1]] ]]

gives

{{1, 2, 3}, {a, c, b}, {x, z, y}}

But ... as I just noticed, this is already covered in @Mr.Wizard's answer long before my edit.


lists = {list1, list2, list3} = {{1, 3, 2}, {a, b, c}, {x, y, z}};

Another option

SortBy[lists\[Transpose], First]\[Transpose]

{{1, 2, 3}, {a, c, b}, {x, z, y}}


Ordering and Part is more efficient than SortBy and Transpose and it can also be done in one pass as I will demonstrate.

I create three lists of different type as described in the question:

a = RandomInteger[999, 500];
b = RandomReal[1, 500];
c = CharacterRange["a", "z"] ~RandomChoice~ 500;

I use the timeAvg function for testing:

SortBy[{a, b, c}\[Transpose], First]\[Transpose] // timeAvg

{a, b, c}[[All, Ordering@a]] // timeAvg

0.00027456

0.000026944

As can be seen second method is more than an order of magnitude faster on this data.

It is noteworthy that these two forms as shown do not perform the same operation because SortBy[list, func] is not a stable sort. Observe:

lists = {{8, 8, 6, 3, 7},
         {"i", "e", "f", "b", "m"},
         {"q", "x", "u", "w", "z"}};

SortBy[lists\[Transpose], First]\[Transpose]

lists[[All, Ordering @ First @ lists]]
{{3, 6, 7, 8, 8}, {"b", "f", "m", "e", "i"}, {"w", "u", "z", "x", "q"}}

{{3, 6, 7, 8, 8}, {"b", "f", "m", "i", "e"}, {"w", "u", "z", "q", "x"}}

You can see see that SortBy has swapped the positions of "i"/"e" and "q"/"x" in the lists so it is not a minimal reordering. This can be corrected however with a different syntax for SortBy:

SortBy[lists\[Transpose], {First}]\[Transpose]
{{3, 6, 7, 8, 8}, {"b", "f", "m", "i", "e"}, {"w", "u", "z", "q", "x"}}

This syntax also speeds up SortBy, but not enough to be competitive with Ordering:

SortBy[{a, b, c}\[Transpose], {First}]\[Transpose] // timeAvg

0.0001248