I want to keep the original order of l1:
l1 = {"qwe", "abc", "abb", "aba", "ddd"};
l2 = {"abc", "abd", "aba", "qwe"};
Intersection[l1, l2]
Output: {"aba", "abc", "qwe"}
Expected output: {"qwe", "abc", "aba"}
I want to keep the original order of l1:
l1 = {"qwe", "abc", "abb", "aba", "ddd"};
l2 = {"abc", "abd", "aba", "qwe"};
Intersection[l1, l2]
Output: {"aba", "abc", "qwe"}
Expected output: {"qwe", "abc", "aba"}
To keep the original order, use Cases[] with Alternatives:
l1 = {"qwe", "abc", "abb", "aba", "ddd"};
l2 = {"abc", "abd", "aba", "qwe"};
Cases[l1, Apply[Alternatives, l2]]
Output: {"qwe", "abc", "aba"}
Use AbsoluteTiming to benchmark this solution - processing time is comparable to Intersection[].
If this helps you, remember to up-vote. :)
AbsoluteTiming[] benchmarks: (see dataset creation instructions below)
Intersection[l1, l2]; // AbsoluteTiming
{0.008827, Null}
Cases[l1, Apply[Alternatives, l2]]; // AbsoluteTiming
{0.003104, Null}
Select[l1, MemberQ[l2, #] &]; // AbsoluteTiming
{2.24958, Null}
Map[If[MemberQ[l2, #], #, Nothing] &, l1]; // AbsoluteTiming
{2.22717, Null}
Reap[If[MemberQ[l2, #], Sow[#]] & /@ l1][[2, 1]]; // AbsoluteTiming
{2.21488, Null}
PositionIndex[Join[l1, l2]] // Select[Length[#] > 1 &] //
Values[#, First] & // Part[Join[l1, l2], #] &; // AbsoluteTiming
{0.033102, Null}
With[{L = Join[l1, l2]},
Part[L, Values[Select[PositionIndex@L, Length@# > 1 &]][[All,
1]]]]; // AbsoluteTiming
{0.032718, Null}
CreateDataStructure["OrderedHashSet", l1]["Intersection", l2][
"Elements"]; // AbsoluteTiming
{0.011508, Null}
list = Map[StringJoin, Tuples[RandomSample[Alphabet[], 5], 6]];
Print["List length: ", Length[list]]
l1 = RandomSample[list, IntegerPart[Length[list]*0.6]];
l2 = RandomSample[list, IntegerPart[Length[list]*0.6]];
List length: 15625
One way to keep the order in l1
is this:
l1 = {"qwe", "abc", "abb", "aba", "ddd"};
l2 = {"abc", "abd", "aba", "qwe"};
Select[l1, MemberQ[l2, #] &]
(* {"qwe", "abc", "aba"} *)
Note that the Select
function has been in
Mathematica since version 1.0. The alternative
Map[If[MemberQ[l2, #], #, Nothing] &, l1]
does the same thing. A variant is
Reap[If[MemberQ[l2, #], Sow[#]] & /@ l1][[2, 1]]
.
Select[l1, MemberQ[l2, #] &]
is similar in spirit, but a bit more elegant.
$\endgroup$
Commented
Jul 27, 2021 at 20:37
You can use the new data structure functionality in M12.1 to do this. For example:
l1 = {"qwe", "abc", "abb", "aba", "ddd"};
l2 = {"abc", "abd", "aba", "qwe"};
ds = CreateDataStructure["OrderedHashSet", l1]["Intersection", l2]["Elements"]
{"qwe", "abc", "aba"}
A bit of explanation. CreateDataStructure["OrderedHashSet", l1]
creates a data structure containing l1
. Then, giving "Intersection", l2
as the arguments of the data structure intersects the contents of the data structure with the set l2
, returning the data structure. Finally, using "Elements" as the argument to the returned data structure gives the remaining elements.
A wonderfully over-engineered solution:
l1 = {"qwe", "abc", "abb", "aba", "ddd"};
l2 = {"abc", "abd", "aba", "qwe"};
PositionIndex[Join[l1, l2]] //
Select[Length[#] > 1 &] //
Values[#, First] & //
Part[Join[l1, l2], #] &
With[{L = Join[l1, l2]}, Part[L, Values[Select[PositionIndex@L, Length@# > 1 &]][[All, 1]]]]
.
$\endgroup$
Using DeleteCases
, Complement
and Alternatives
:
DeleteCases[l1, Alternatives @@ Complement[l1, l2]]
(*{"qwe", "abc", "aba"}*)
Since V 13.1
there is DeleteElements
l1 = {"qwe", "abc", "abb", "aba", "ddd"};
l2 = {"abc", "abd", "aba", "qwe"};
DeleteElements[l1, Complement[l1, l2]]
{"qwe", "abc", "aba"}
Clear["Global`*"];
l1 = {"qwe", "abc", "abb", "aba", "ddd"};
l2 = {"abc", "abd", "aba", "qwe"};
r1 = # -> # & /@ l1
r2 = # -> # & /@ l2
KeyTake[r2, Keys@r1] // Keys
{"qwe", "abc", "aba"}