# Tracing pairs form a list

I have a 4 list of pairs as

P1 = {{4, 17}, {19, 32}, {-5, 8}};
P2 = {{16, 29}, {31, 44}, {40, 53}};
P3 = {{55, 68}, {64, 77}, {79, 92}};
P4 = {{76, 89}, {88, 101}, {91, 104}};


and I combine this 4 list by

Q = Join[P1, P2, P3, P4]


and then i sort it with respect to first element in pairs b

Sort[Q, #1[[1]] < #2[[1]] &]


But I want to trace also the appearing pairs in last result with the corresponding list. That is {-5, 8} is came from P1. How to do this. Please help. Thank you.

Many ways to do this. Read the documentation re: associations, etc. Here's a quick and simple way. Note I changed your symbols to lowercase initials (bad idea to use capital initials, risks clashing with built-in symbols). Since you do not specify if duplicate pairs can appear in multiple lists, I've not accounted for that, caveat lector...

p1 = {{4, 17}, {19, 32}, {-5, 8}};
p2 = {{16, 29}, {31, 44}, {40, 53}};
p3 = {{55, 68}, {64, 77}, {79, 92}};
p4 = {{76, 89}, {88, 101}, {91, 104}};
q = Join[p1, p2, p3, p4];
qs = SortBy[q, First];

(* here, strings are used to represent the symbols assigned to your lists *)
qs
qs /. Join @@ (Thread[ToExpression[#] -> #] & /@ {"p1", "p2", "p3","p4"})
(* put these "together" *)


{{-5, 8}, {4, 17}, {16, 29}, {19, 32}, {31, 44}, {40, 53}, {55, 68}, {64, 77}, {76, 89}, {79, 92}, {88, 101}, {91, 104}}

{"p1", "p1", "p2", "p1", "p2", "p2", "p3", "p3", "p4", "p3", "p4", \ "p4"}

{{-5, 8} -> "p1", {4, 17} -> "p1", {16, 29} -> "p2", {19, 32} -> "p1", {31, 44} -> "p2", {40, 53} -> "p2", {55, 68} -> "p3", {64, 77} -> "p3", {76, 89} -> "p4", {79, 92} -> "p3", {88, 101} -> "p4", {91,104} -> "p4"}

Consider initializing differently.

p[1] = {{4, 17}, {19, 32}, {-5, 8}};
p[2] = {{16, 29}, {31, 44}, {40, 53}};
p[3] = {{55, 68}, {64, 77}, {79, 92}};
p[4] = {{76, 89}, {88, 101}, {91, 104}};

SortBy[Join @@ Table[# -> i & /@ p[i], {i, 4}], First]

(* {{-5, 8} -> 1, {4, 17} -> 1, {16, 29} -> 2 ... *)

• @Kuba I know first elements are obtained here by #[[1,1]]&, but isn't a pair of elements (via First only) compared by their first elements and on a tie by second? I don't know if OP needs were stated that precisely. :)
– BoLe
Aug 4, 2016 at 8:42

Create a new list with the list name and then Sort.

s1 = P1 /. {x_, y_} -> {x, y, "P1"}
s2 = P2 /. {x_, y_} -> {x, y, "P2"}
s3 = P3 /. {x_, y_} -> {x, y, "P3"}
s4 = P4 /. {x_, y_} -> {x, y, "P4"}

Q1 = Join[s1, s2, s3, s4]
Q2 = Sort[Q1, #1[[1]] < #2[[1]] &]
Q3 = Q2[[All, {1, 2}]]


Q2 will show the sorted list with list name and Q3 will show only the elements.

As the previous answers show, in order to "trace" the data you are sorting, you must, soon or late, build a new data structure where each data element "knows" where it comes from.

1. Something like: {{{4,17},"p1"}, {{19,32},"p1"}, ... is probably the simplest structure to deal with. You can directly apply Sort or SortBy on it. For example:

q={{{4, 17}, "p1"}, {{19, 32}, "p1"}, {{-5, 81}, "p1"}, {{16, 29}, "p2"},
{{31, 44}, "p2"}, {{40, 53}, "p2"}};

SortBy[q,#[[1,1]]&]

{{{-5, 81}, "p1"}, {{4, 17}, "p1"}, {{16, 29}, "p2"}, {{19, 32}, "p1"},
{{31, 44}, "p2"}, {{40, 53}, "p2"}}


If you can't or for some reasons you don't want to build such a list from the start, you can build it automatically from the existing definitions of p1, p2 ... Here is a way to do it with this function:

tag[x_List, func_: List] :=
Module[{symbols = ToString /@ Unevaluated /@ (Unevaluated@x)},
Join @@ MapThread[Thread[func[##]] &, {ToExpression@#, #} &@symbols]]

SetAttributes[tag, HoldAll]


then for example:

p1 = {{4, 17}, {19, 32}, {-5, 81}};
p2 = {{16, 29}, {31, 44}, {40, 53}};

q = tag[{p1, p2}]

{{{4, 17}, "p1"}, {{19, 32}, "p1"}, {{-5, 81}, "p1"}, {{16, 29}, "p2"},
{{31, 44}, "p2"}, {{40, 53}, "p2"}}


You can also build a "subscripted" form of the list with :

q = tag[{p1, p2}, Subscript]


This form will work exactly the same way as previously with Sort or SortBy (SortBy[q,#[[1,1]]&])

2. Dataset

This is most probably an overkill, but you might be interested in converting your data to a more structured Dataset. I let you explore the documentation and examples about it on this site and give you just an idea of how Dataset works. For example, let convert the previous q list to such a dataset:

q = tag[{p1, p2}];
ds = Dataset[
AssociationThread @@@ Thread[{{"val", "symb"}, q}, List, {-1}]]


Then, to sort by the the first element in the "val" column:

ds[SortBy[#val[[1]] &]]
(* or : SortBy[ds, #val[[1]] &] *)


Then you can extract the column you want, chain with other action, ...