14
$\begingroup$

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.)

$\endgroup$
1
  • $\begingroup$ 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. $\endgroup$
    – Kvothe
    Jan 17, 2017 at 10:58

3 Answers 3

17
$\begingroup$

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}}|>

$\endgroup$
1
  • $\begingroup$ Thank you. Very elegant. Figuring out how your answer works was definitely educational. $\endgroup$
    – Kvothe
    Jan 17, 2017 at 11:13
7
$\begingroup$

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}}|>
$\endgroup$
4
$\begingroup$
l1 = {a, b, c};
l2 = {b, c, e};
l3 = Intersection[l1, l2]

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.