6
$\begingroup$

i have two lists of strings with unequal numbers of subelements in each.

i would like to remove from lis2 all instances where a pattern in lis1 appears in lis2:

lis1 = {{"a","b","c","d"}, {"w","x","y","z"}}

lis2 = {{"q","a","b","c","d","r"},{"j","k","l","m","n","o"}}

to give:

res = {"j","k","l","m","n","o"}

Thanks for ideas.

Addendum: Thanks for your replies!

I can't seem to make any of the suggestions work with the following lists:

lis1 = {{"a", "19", "b", "29"}, {"c", "42", "d", "13"}, {"e", "42", "f","10"}, {"g", "13", "h", "23"}, {"i", "14", "j", "26"}, {"k", "14", "l", "34"}, {"m", "7", "n", "77"}}

and

lis2 = {{DateObject[{2022, 9, 3}, "Day"], "w", "17", "x", "48", "AWAY", False}, {DateObject[{2022, 9, 3}, "Day"], "y", "0", "z", "55","AWAY", True}, {DateObject[{2022, 9, 3}, "Day"], "g", "13", "h","23", "AWAY", True}, {DateObject[{2022, 9, 3}, "Day"], "o", "13","p", "21", "AWAY", True}, {DateObject[{2022, 9, 3}, "Day"], "q","14", "r", "28", "AWAY", True}, {DateObject[{2022, 9, 3}, "Day"],"s", "1", "t", "2", "AWAY", True}}

The desired result is:

{{DateObject[{2022, 9, 3}, "Day"], "w", "17","x","48","AWAY", False}, {DateObject[{2022, 9, 3}, "Day"], "y", "0","z","55", "AWAY", True}, {DateObject[{2022, 9, 3}, "Day"], "o", "13", "p", "21", "AWAY", True}, {DateObject[{2022, 9, 3}, "Day"], "q", "14", "r", "28", "AWAY", True}, {DateObject[{2022, 9, 3}, "Day"], "s", "1", "t", "2", "AWAY", True}}

...in which the element containing the pattern {"g","13","h","23"} from lis1 is deleted from lis2.

$\endgroup$
5
  • 1
    $\begingroup$ Try: Cases[lis2, Except[{___, PatternSequence["a", "b", "c", "d"], ___}]] $\endgroup$ Commented Sep 6, 2022 at 18:27
  • $\begingroup$ Post-addendum: The pattern {"g","13","h","23"} is deleted from lis2 because it is present in lis1. If you want to check for a complete signature match over a number of fields in lis2 then this could be another question. Right now any sub-sequence will result in a match, which is kind of limiting. In that case, I think the addendum can be posted as a new question. $\endgroup$
    – Syed
    Commented Sep 8, 2022 at 2:05
  • $\begingroup$ Thank you. Will do. $\endgroup$
    – Suite401
    Commented Sep 8, 2022 at 2:24
  • $\begingroup$ try DeleteCases[Alternatives @@ ({_, ##, ___} & @@@ lis1)] @ lis2? $\endgroup$
    – kglr
    Commented Sep 8, 2022 at 12:42
  • $\begingroup$ Yes kglr that works, thank you so much! $\endgroup$
    – Suite401
    Commented Sep 9, 2022 at 2:49

4 Answers 4

7
$\begingroup$

pattern in lis1 appears in lis2

You mean if the intersection between any subsets is zero, you keep it? So even if one letter shows up between the two sets, then this is a hit, right? so you scan lis2, checking if any subset has no intersection with any of the sublists in lis1.

How about

lis1 = {{"a", "b", "c", "d"}, {"w", "x", "y", "z"}}
lis2 = {{"q", "a", "b", "c", "d", "r"}, {"j", "k", "l", "m", "n", 
   "o"}, {"a"}, {"w", "x"}, {"h", "v"}}
Cases[lis2, x_ /; Length[Flatten[Intersection[x, #] & /@ lis1]] == 0]

Mathematica graphics

For your example

lis1 = {{"a", "b", "c", "d"}, {"w", "x", "y", "z"}}
lis2 = {{"q", "a", "b", "c", "d", "r"}, {"j", "k", "l", "m", "n", "o"}}
Cases[lis2, x_ /; Length[Flatten[Intersection[x, #] & /@ lis1]] == 0]

Mathematica graphics

There are many other ways to do this in Mathematica. At least 9 more ways I would say.

$\endgroup$
6
$\begingroup$

Using @Nasser's example data:

lis1 = {{"a", "b", "c", "d"}, {"w", "x", "y", "z"}}
lis2 = {{"q", "a", "b", "c", "d", "r"}, {"j", "k", "l", "m", "n", 
   "o"}, {"a"}, {"w", "x"}, {"h", "v"}}

Extract[lis2
 , Position[
  LongestCommonSubsequence[#, Catenate@lis1] & /@ lis2
  , {}
  ]
 ]

{{"j", "k", "l", "m", "n", "o"}, {"h", "v"}}

$\endgroup$
5
$\begingroup$

Using ContainsAll and the If statement:

Map[If[ContainsAll[#, Intersection[Flatten@lis1, Flatten@lis2]] === True, Nothing, #] &, lis2]
(*{{"j", "k", "l", "m", "n", "o"}}*)

Or, using ContainsAny and the If statement:

Map[If[ContainsAny[#, Intersection[Flatten@lis1, Flatten@lis2]] === True, Nothing, #] &, lis2]
(*{{"j", "k", "l", "m", "n", "o"}}*)
$\endgroup$
2
$\begingroup$
a = 
 {{"a", "b", "c", "d"}, {"w", "x", "y", "z"}};

b = 
 {{"q", "a", "b", "c", "d", "r"}, {"j", "k", "l", "m", "n", "o"}, 
  {"a"}, {"w", "x"}, {"h", "v"}};

Using SequenceAlignment

Pick[b, FreeQ[Alternatives @@ a] @ SequenceAlignment[#, Flatten @ a] & /@ b]

{{"j", "k", "l", "m", "n", "o"}, {"a"}, {"h", "v"}}

The above also shows the {"a"}. If this is not wanted:

Cases[{_, __}] @ %

{{"j", "k", "l", "m", "n", "o"}, {"h", "v"}}

$\endgroup$

Your Answer

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

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