7
$\begingroup$

How can I order a list to match the order of anoter list ?

For example: Suppose I have the lists x = {3, 1, 5, 7} and y = {3, 7, 1, 5}. How can I order x to have the order of y?

This question is interesting when each element of x has composite values, for example, as a list or an association.

$\endgroup$

2 Answers 2

11
$\begingroup$

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]
$\endgroup$
1
  • 1
    $\begingroup$ You are right, it is fast and traditional way to do a such kind of sorting. Related: 1, 2, 3. Anyway, +1, I cannot find similar Q&A. $\endgroup$
    – ybeltukov
    Commented Nov 21, 2015 at 16:05
2
$\begingroup$

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
$\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.