# An Intersection function on lists that saves intersection positions

I would like an intersection function on lists like Intersection that also stores the coordinates of the intersections. For instance for {a,b,c} and {b,c,e} would give something like {{b,2,1},{c,3,2}}.

If more elements match preferably it saves all of the positions. So {a,b,c,a} and {d,c,a,c} would give something like {a,{1,4},3},{c,3,{2,4}}}.

Can this be done easily?

(Only a comparison of two lists is needed for the present purpose. But a more general function that can be applied to any number of lists might be nice to have ready in the future too.)

• Thanks everybody! Great answers. Hard to choose who to accept but since ciao has an answer that works for any number of lists without adaption I've gone with that one. Jan 17, 2017 at 10:58

I'll take "... give something like..." to mean we can take some liberties with output format.

myFn=Merge[KeyIntersection[PositionIndex /@ {##}], Identity]&;


will produce an association with the desired information, works with any number of lists.

l1 = {a, b, c, a};
l2 = {d, c, a, c};
l3 = {z, d, d, a, c, k};

myFn[l1,l2,l3]


<|a -> {{1, 4}, {3}, {4}}, c -> {{3}, {2, 4}, {5}}|>

• Thank you. Very elegant. Figuring out how your answer works was definitely educational. Jan 17, 2017 at 11:13

Simple-minded solution:

intersectionPositions[ls__List] :=
GroupBy[Flatten[Outer[{#2, Flatten[Position[#1, #2]]} &,
{ls}, Intersection[ls], 1], 1], First -> Last]

intersectionPositions[{a, b, c, a}, {d, c, a, c}]
<|a -> {{1, 4}, {3}}, c -> {{3}, {2, 4}}|>

intersectionPositions[{a, b, c, a}, {d, c, a, c}, {z, d, d, a, c, k}]
<|a -> {{1, 4}, {3}, {4}}, c -> {{3}, {2, 4}, {5}}|>

l1 = {a, b, c};
l2 = {b, c, e};
l3 = Intersection[l1, l2]

{#, Flatten[Position[l1, #]], Flatten[Position[l2, #]]} & /@ l3