# Matching position of same elements in two lists

Suppose I have two lists of the same size as follows:

A1 = {a, b, c, d};
A2 = {c, a, b, d};


I want to construct a function that gives the relation between positions of same elements in both lists.

For example, we see that

a = A1[[1]] = A2[[2]]
b = A1[[2]] = A2[[3]]


and so on.

With DeleteCases and using Alternatives, I can tell whether the two elements of two lists are the same or not, but I can not tell which position of them are in the same.

Is there any smart way to find out their relations? In the above example, I want the code to return a list:

{{1, 2}, {2, 3}, {3, 1}, {4, 4}}


Update

Ben Izd (in a comment) has suggested the following neat modification: Use Catenate rather than Identity to avoid mapping Flatten

Merge[PositionIndex/@{A1,A2},Catenate]

(* <|a -> {1, 2}, b -> {2, 3}, c -> {3, 1}, d -> {4, 4}|> *)


Merge[{PositionIndex[A1],PositionIndex[A2]},Identity]

(* <|a -> {{1}, {2}}, b -> {{2}, {3}}, c -> {{3}, {1}}, d -> {{4}, {4}}|> *)


Or:

Map[Flatten,Merge[{PositionIndex[A1],PositionIndex[A2]},Identity]]

%//Values

(*
<|a -> {1, 2}, b -> {2, 3}, c -> {3, 1}, d -> {4, 4}|>

{{1, 2}, {2, 3}, {3, 1}, {4, 4}}
*)

• (+1) You can replace Identity with Catenate to skip mapping Flatten. Aug 16, 2023 at 4:55

You can use Ordering

ar1 = {a, b, c, d}
ar2 = {c, a, b, d}



yields: {{1, 2}, {2, 3}, {3, 1}, {4, 4}}

Using Permutation:

Transpose@{Range[Length[A1]],
PermutationList[FindPermutation[A1, A2], Length[A1]]}

(* Out: {{1, 2}, {2, 3}, {3, 1}, {4, 4}} *)


Using Query and Dataset:

Query[Merge[#, Flatten] & /* Dataset, PositionIndex][{A1, A2}]


ds =
Query[Merge[#, Flatten] & /*
Query[All, AssociationThread[{"A1", "A2"} -> #] &] @ # & /* Dataset,
PositionIndex][{A1, A2}]


Now, for example:

ds[{Key @ a, Key @ d}, "A2"]


Using DistanceMatrix:

Position[DistanceMatrix[A1, A2], 0]


Using Position:

Transpose@{Range@Length@A1, Flatten[Position[A2, #] & /@ A1]}


Using OrderingBy:

MapIndexed[{First@#2, #1} &, OrderingBy[A2, Position[A1, #] &]]


Result

{{1, 2}, {2, 3}, {3, 1}, {4, 4}}

One possible way

A1={a,b,c,d};
A2={c,a,b,d};

MapIndexed[{First[#2], Flatten@Position[A2, #1]} &, A1]


If you only want the first position that match, add First

 MapIndexed[{First[#2],First@Flatten@Position[A2,#1]}&,A1]


Another way using GroupBy:

Values@Merge[Keys@GroupBy[{A1, A2}, PositionIndex], Join @@ # &]

(*{{1, 2}, {2, 3}, {3, 1}, {4, 4}}*)