# 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.
Commented Mar 27, 2019 at 18:58
• Is there a better example to show what you want? Doesn't Sort[list2] give the desired output? Commented Mar 27, 2019 at 23:24
• list2[[OrderingBy[list1, -#[[2]] &]]] in the next release... Commented Mar 27, 2019 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]]]]. Commented Mar 27, 2019 at 20:47
• Doh...fixed it. Both ways give the same answer, which leads to sloppy debugging. Commented Mar 27, 2019 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.
Commented Mar 27, 2019 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. Commented Mar 27, 2019 at 23:34
p = {{a, 12}, {b, 10}, {c, 4}};

q = {{b, 5}, {a, 4}, {c, 1}};

n = Length[p];


Using SubsetMap (new in 12.0)

SubsetMap[Last /@ Sort[q] &, p, Table[{i, 2}, {i, n}]]


{{a, 4}, {b, 5}, {c, 1}}

l1 = {{a, 12}, {b, 10}, {c, 4}};

l2 = {{b, 5}, {a, 4}, {c, 1}};


Using OrderingBy and RotateLeft:

l2[[RotateLeft@OrderingBy[l1, Last]]]

(*{{a, 4}, {b, 5}, {c, 1}}*)