# Sort a list by elements of another list

I know there are a plenty of other questions here which appear to be similar, however I did not found anything which could give me a hint.

I have two lists:

list1 = {{A, 12}, {B, 10}, {C, 4}}; (*ordered according to the second column*)
list2 = {{B, 5}, {A, 4}, {C, 1}};   (*ordered according to the second column*)


Now I want to sort list2according to the list1-order so the output should be:

(* {{A, 4}, {B, 5}, {C, 1}} *)

• to be more specific list2should be sorted according to the first column of list1 – M.A. Mar 27 '19 at 18:58
• Is there a better example to show what you want? Doesn't Sort[list2] give the desired output? – Jason B. Mar 27 '19 at 23:24
• list2[[OrderingBy[list1, -#[[2]] &]]] in the next release... – Daniel Lichtblau Mar 27 '19 at 23:37

Permute[list2, FindPermutation[ list2[[All,1]] , list1[[All,1]] ] ]


{{A, 4}, {B, 5}, {C, 1}}

• Actually, I like your solution much better than mine. By the way, when I found out that my former solution was incorrect, I also realized that your solution should better be Permute[list2, FindPermutation[list2[[All, 1]], list1[[All, 1]]]]. – Henrik Schumacher Mar 27 '19 at 20:47
• Doh...fixed it. Both ways give the same answer, which leads to sloppy debugging. – MikeY Mar 27 '19 at 21:04
list1 = {{A, 12}, {B, 10}, {C, 4}, {D, 2}};
list2 = {{A, 4}, {D, 11}, {B, 5}, {C, 1}};

idx = Lookup[
list2[[All, 1]]
];
result = list2;
result[[idx]] = list2;
result


{{A, 4}, {B, 5}, {C, 1}, {D, 11}}

• works well with the example lists. However, something goes wrong when I use other lists with Strings in the first columns instead of A, Band C.... – M.A. Mar 27 '19 at 21:29

ugly but fast:

list2[[Ordering[list2[[All, 1]]][[Ordering[Ordering[list1[[All, 1]]]]]]]]


{{A, 4}, {B, 5}, {C, 1}}

even faster:

result = list2;
result[[Ordering[list1[[All, 1]]]]] = SortBy[list2, First];
result


{{A, 4}, {B, 5}, {C, 1}}

## benchmarks

s = 10^7;
list1 = Transpose[{PermutationList@RandomPermutation[s],
RandomInteger[{0, 10}, s]}];
list2 = Transpose[{PermutationList@RandomPermutation[s],
RandomInteger[{0, 10}, s]}];

(* my first solution *)
result1 = list2[[Ordering[list2[[All, 1]]][[Ordering[Ordering[list1[[All, 1]]]]]]]]; //AbsoluteTiming//First
(* 8.6416 *)

(* my second solution *)
result2 = Module[{L},
L = list2;
L[[Ordering[list1[[All, 1]]]]] = SortBy[list2, First];
L]; //AbsoluteTiming//First
(* 6.89593 *)

(* MikeY's solution *)
result3 = Permute[list2, FindPermutation[list2[[All, 1]], list1[[All, 1]]]]; //AbsoluteTiming//First
(* 15.808 *)

(* Henrik Schumacher's solution *)
result4 = Module[{idx, L},
idx = Lookup[AssociationThread[list1[[All, 1]] -> Range[Length[list1]]], list2[[All, 1]]];
L = list2;
L[[idx]] = list2;
L]; //AbsoluteTiming//First
(* 31.7412 *)

(* make sure all methods agree *)
result1 == result2 == result3 == result4
(* True *)

• Thanks for the benchmark. I started down the Ordering road, but went for parsimony of expression. Mild bummer that it is at least twice as slow as the best method. – MikeY Mar 27 '19 at 23:34