# 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. – Kvothe Jan 17 '17 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. – Kvothe Jan 17 '17 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