How to order a list to match the order of another list?
Using Ordering
it's possible to do this. Ordering
can be seen as a permutation that brings a list to the identity permutation. And applying Ordering
again to this permutation we get the inverse permutation that brings a list from identity to the original order. Using these observations:
OrderingToTarget[list_, sourceIds_, targetIds_] :=
list[[Ordering @ sourceIds]][[Ordering @ Ordering@targetIds]]
OrderingToTarget[x, x, y]
Inspired by Sort two lists at the same time, based on another here is a different approach:
permuteLike[a_, b_] :=
Module[{x = a},
x[[Ordering @ b]] = Sort[a];
x
]
This proves to be somewhat faster and I find it somehow more pleasing as well.
a = {"f", "a", "h", "y", "c", "d"};
b = {"w", "t", "q", "o", "b", "p"};
OrderingToTarget[a, a, b]
a ~permuteLike~ b
{"y", "h", "f", "c", "a", "d"} {"y", "h", "f", "c", "a", "d"}
{a, b} = RandomInteger[3*^6, {2, 1*^6}];
OrderingToTarget[a, a, b] // RepeatedTiming // First
a ~permuteLike~ b // RepeatedTiming // First
0.3234 0.228