4
$\begingroup$

Say a nested list datatest and a sublist searchterm, I would like to pick up the lists in the datatest which contains searchterm and searchterm appears in the first position (allowing maximal offset 5) of each lists in datatest.

For example:

datatest = {{8, 5, 1, 1, 2, 3, 6, 1, 1, 2, 4}, {1, 4, 1, 2, 3, 6, 2, 3, 1, 3}, 
{0, 1, 1, 1, 1, 1, 2, 3, 6, 11}, {4, 5, 1, 1, 2, 3, 6, 1, 1, 2, 4}, {1, 4, 5, 2, 3, 6, 2, 3, 1, 3}};

searchterm={1,2,3,6};

I would like to have the results

{{8, 5, 1, 1, 2, 3, 6, 1, 1, 2, 4}, {1, 4, 1, 2, 3, 6, 2, 3, 1, 3}, {4, 5, 1, 1, 2, 3, 6, 1, 1, 2, 4}}

term {0, 1, 1, 1, 1, **1, 2, 3, 6**, 11} is not fulfilled since it appears in the position 6, which is >5.

My way is following (not a good method, results are in Selectdata):

datatest = {{8, 5, 1, 1, 2, 3, 6, 1, 1, 2, 4}, {1, 4, 1, 2, 3, 6, 2, 3, 1, 3}, {0, 1, 1, 1, 1, 1, 2, 3, 6, 11}, 
{4, 5, 1, 1, 2, 3, 6, 1, 1, 2, 4}, {1, 4, 5, 2, 3, 6, 2, 3, 1, 3}};
searchterm= {1, 2, 3, 6};

pos = Flatten[Map[First /@ SequencePosition[#, searchterm] &]@datatest];
pickpos = Select[pos, # < 5 &]; (*pick up only offset position is below 5*)

Selectdata = {};
count = 0;
For[ii = 1, ii <= Length[pickpos], ii++,
 
 index = Flatten[Position[pos, pickpos[[ii]]]];
 If[Length[index] == 1,
     AppendTo[Selectdata, datatest[[index[[1]]]]],
     count++;
     AppendTo[Selectdata, datatest[[index[[count]]]]];
  ];
 ]

The above code only works for the defined datatest (use count++ might not work generally) . So is there any simple solution or more general way to do it when datatest gets large?

$\endgroup$
7
$\begingroup$

You could use Cases:

Cases[datatest, {z__, Sequence @@ searchterm, ___} /; Length[{z}] < 5]

{{8, 5, 1, 1, 2, 3, 6, 1, 1, 2, 4}, {1, 4, 1, 2, 3, 6, 2, 3, 1, 3}, {4, 5, 1, 1, 2, 3, 6, 1, 1, 2, 4}}

$\endgroup$
1
  • $\begingroup$ I have used Cases before but didn’t do the trick z__ and length[z]<5. That’s good trick! Thank you ! $\endgroup$ – Xuemei Jun 3 at 18:07
4
$\begingroup$

You can also use Cases and specify maximal offset using Repeated:

Cases[{Repeated[_, 5 - 1], Sequence @@ searchterm, ___}] @ datatest

{{8, 5, 1, 1, 2, 3, 6, 1, 1, 2, 4}, {1, 4, 1, 2, 3, 6, 2, 3, 1, 3}, {4, 5, 1, 1, 2, 3, 6, 1, 1, 2, 4}}

$\endgroup$
1
  • $\begingroup$ that's also a nice solution, thank you! $\endgroup$ – Xuemei Jun 4 at 6:52
1
$\begingroup$
datatest//Pick[#,MatchQ[#,{___,1,2,3,6,___}]&/@#[[All,;;8]],True]&)

{{8, 5, 1, 1, 2, 3, 6, 1, 1, 2, 4}, {1, 4, 1, 2, 3, 6, 2, 3, 1, 3},

{4, 5, 1, 1, 2, 3, 6, 1, 1, 2, 4}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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