# Sorting elements in a table with respect to another table

I have two tables, each having three rows (R1, R2 & R3). The elements of R2 & R3 are same in two tables but in different orders. The elements in row R1 are different in two tables. I want to sort the elements of second table such that rows R2 & R3 become similar. For example, If

T1 = {{t1, 1, 2}, {t2, 2, 3}, {t3, 3, 2}, {t4, 2, 1}}

T2 = {{u1, 3, 2}, {u2, 1, 2}, {u3, 2, 1}, {u4, 2, 3}}


How can I sort elements of T2 such that second and third elements of each row are same as T1. That is

T3 = {{u2, 1, 2}, {u4, 2, 3}, {u1, 3, 2}, {u3, 2, 1}}


thanks

• Are there duplicate values in the 2nd and 3rd columns of the table? – Szabolcs Sep 30 '17 at 8:52
• For example {t1, 1, 2} and {t2, 2, 1} are possible at same time, so are {t1, 1, 1} and {t2, 2, 2}. But {t1, 1, 2 } and {t2, 1, 2} are not possible. For a set of last two elements, first row can't have two different elements. thanks – user49535 Sep 30 '17 at 9:07
• Then the association method will work. – Szabolcs Sep 30 '17 at 9:17

There are multiple ways. One is to use Ordering.

Let p1 and p2 be the permutations that order T1 and T2 by their R2 & R3.

p1 = Ordering[T1[[All, 2 ;; 3]]]
(* {1, 4, 2, 3} *)

p2 = Ordering[T2[[All, 2 ;; 3]]]
(* {2, 3, 4, 1} *)


Let's invert p1:

invp1 = Ordering[p1]
(* {1, 3, 4, 2} *)


Then we sort T2, then transform that to the order seen in T1:

T2[[p2]][[invp1]]
(* {{u2, 1, 2}, {u4, 2, 3}, {u1, 3, 2}, {u3, 2, 1}} *)


Another way is to use Association

a1 = AssociationThread[
T1[[All, 2 ;; 3]],
T1[[All, 1]]
]
(* <|{1, 2} -> t1, {2, 3} -> t2, {3, 2} -> t3, {2, 1} -> t4|> *)

T2[[All, 2 ;; 3]],
T2[[All, 1]]
]
(* <|{3, 2} -> u1, {1, 2} -> u2, {2, 1} -> u3, {2, 3} -> u4|> *)


This assumes that there were no duplicates {R2, R3} pairs.

KeyTake[a2, Keys[a1]]
(* <|{1, 2} -> u2, {2, 3} -> u4, {3, 2} -> u1, {2, 1} -> u3|> *)


If you have Mathematica 10.0+ and no trouble with duplicate keys, I would use the association-based method, and I would keep the data structures as associations instead of tables.

• Thanks. Association is working fine for me..One more thing, how can I convert <|{1, 2} -> u2, {2, 3} -> u4, {3, 2} -> u1, {2, 1} -> u3|> back to table form like {{u2, 1, 2}, {u4, 2, 3}, {u1, 3, 2}, {u3, 2, 1}}. – user49535 Sep 30 '17 at 10:21
• I tried - MapThread[Append, {Values[KeyTake[a2, Keys[a1]]], Keys[KeyTake[a2, Keys[a1]]]}] but coming back with error Append::normal: Nonatomic expression expected at position 1 in Append[u2,{1,2}]. – user49535 Sep 30 '17 at 10:44
• @user49535 KeyValueMap[Prepend, ...]. But if you need the table form, use the full lists as association values instead of just the first element. Then you can just use Values in the end. – Szabolcs Sep 30 '17 at 11:31
• I am struggling with this small issue, can you please elaborate. Not able to get back {{u2, 1, 2}, ....} by any method. Could this be because of u2 not being a numerical value ? – user49535 Oct 1 '17 at 10:44

In addition to @Szabolcs's method, a more straightforward approach might be SortBy:

SortBy[T2, Position[T1[[All, 2 ;; 3]], #[[2 ;; 3]]] &]
(* {{u2, 1, 2}, {u4, 2, 3}, {u1, 3, 2}, {u3, 2, 1}} *)


which gives the answer you want.