# Preserving a bijection between arrays when shuffling elements in one array

Imagine I have two lists of elements like the following:

listOne = RandomReal[{0,2}, {100,2}];
listTwo = RandomReal[{0,2}, {100,2}];


Let $f: X \to Y$ be a bijection or one-to-one correspondence between the elements in listOne and the elements in listTwo.

I can shuffle the elements in listOne as follows:

listOne = RandomSample[listOne, Length[listOne]];


However, is there a way for me to perform the above shuffling operation while preserving the bijection $f$? In other words, can I shuffle the elements in listOne and listTwo in precisely the same manner?

-
p.s. There's no need for Length[listone]. – Kuba Oct 29 '13 at 21:07
@MikeHoneychurch I just saw your comment. I was a little slow on the pickup for rule replacement, but I think I get it now. – RTaylor Oct 29 '13 at 21:42
Personally I don't see this as a duplicate. Could one of those who closed the question show how one of the answers to the other question can be applied to this question? – Mike Honeychurch Oct 29 '13 at 21:59
@MikeHoneychurch To my mind, both of the highest-voted answers there apply to this question quite directly, so much so that I don't know what else to add. – Leonid Shifrin Oct 29 '13 at 22:15
@LeonidShifrin I agree with Mike Honeychurch; those seem to require that one list start off life ordered. [If I'm wrong, please accept Mike's humble apology..] – Daniel Lichtblau Oct 29 '13 at 23:41

Just create an ordering list and use Part:

listOne = {1, 2, 3};
listTwo = {4, 5, 6};

order = RandomSample[Range[Length[listOne]]]
(* {2, 3, 1} *)

listOne[[order]]
(* {2, 3, 1} *)

listTwo[[order]]
(* {5, 6, 4} *)

-
+1 Geez I normally always choose Part over other methods but overlooked that. My morning coffee hasn't kicked in yet -- brain still frozen – Mike Honeychurch Oct 29 '13 at 21:11
@MikeHoneychurch, I have a time-zone advantage, my brain has been steeping in coffee all day :-) – Simon Woods Oct 29 '13 at 21:17

If it's a bijection you can for example do this:

s1 = RandomSample[listOne]
s2 = s1 /. MapThread[Rule, {listOne, listTwo}, 1]

-
I would have gone with Dispatch@Thread[Rule[listOne, listTwo]]. Not sure but might be faster for large lists. – Mike Honeychurch Oct 29 '13 at 21:08
@Kuba Thanks it's good to know that you can do this. – RTaylor Oct 29 '13 at 21:20
This doesn't work if listOne contains duplicates. (Since the question is about Mathematica lists/arrays, other site users should be aware of this limitation.) – Michael E2 Oct 30 '13 at 9:58
@MichaelE2 OP gives the assumption that it is bijection. So there are no duplicates, or if there are they are reffering to duplicate positions in the second list. Or I missed something? – Kuba Oct 30 '13 at 11:10
A one-to-one correspondence between two Lists, which are ordered and permit duplicates, is different than a one-to-one correspondence between sets. The site being about Mathematica, it seems fair to presume that an array is a List, not a mathematical set. Because the Q&A format is for everyone, I think the distinction ought to be made clear for those who would adapt a solution to their own use-case. If sets are meant - I agree the possibility is suggested by "bijection" - then the question should make that clear. I had a similar disagreement about another of the OP's questions. :) – Michael E2 Oct 30 '13 at 12:49

Although I have used Simon's method many times I think it is somewhat cleaner in this case to transpose the data, shuffle, and transpose again:

l1 = {a, b, c, d, e};
l2 = {v, w, x, y, z};

RandomSample[{l1, l2}\[Transpose]]\[Transpose]

{{e, c, b, a, d}, {z, x, w, v, y}}


The \[Transpose] symbol appears as T in the Front End:

-
I agree that this is cleaner. In fact I'd normally only use the method I posted if there was some need later on to undo the shuffle. – Simon Woods Oct 31 '13 at 22:18