10
$\begingroup$

I have a list:

lis = {{1,2,3},{"True",3,4,5},{6,5},{3},{6,4},{"True",2,1},{5},{5,6},{7,8,9}}

I want to make a new list consisting of elements of lis that begin with "True", and include the next two elements directly following, thus making triplets:

res = {({"True",3,4,5},{6,5},{3}},{{"True",2,1},{5},{5,6}}}

I can't see how to use Cases here. Thanks for ideas.

$\endgroup$

5 Answers 5

8
$\begingroup$

SequenceCases:

SequenceCases[lis, {{"True", ___}, _, _}]
{{{"True", 3, 4, 5}, {6, 5}, {3}}, {{"True", 2, 1}, {5}, {5, 6}}}

Split + Cases:

Cases[p : {{"True", ___}, ___} :> Take[p, UpTo[3]]] @ Split[lis, #2[[1]] != "True" &]
{{{"True", 3, 4, 5}, {6, 5}, {3}}, {{"True", 2, 1}, {5}, {5, 6}}}

Position + Part:

lis[[# ;; UpTo[# + 2]]] & /@ Flatten@Position[lis, {"True", ___}]
{{{"True", 3, 4, 5}, {6, 5}, {3}}, {{"True", 2, 1}, {5}, {5, 6}}}
$\endgroup$
4
$\begingroup$

Defining a utiilty function that appends subsequent positions to the list. This can be changed as required without affecting other parts of the solution.

lp2[k_List] := {First@k, First@k + 1, First@k + 2}

Test: lp2[{2}] (* {2,3,4} *)

sel = lp2 /@ Position[lis, {"True", ___}]

Part[lis, #] & /@ sel

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

$\endgroup$
4
$\begingroup$

Selecting indices, and do something :

lis[[# ;; # + 2]] & /@ 
 Select[Range[Length[lis]], lis[[#, 1]] === "True" &]
$\endgroup$
3
$\begingroup$
lis = {{1, 2, 3}, {"True", 3, 4, 5}, {6, 5}, {3},
      {6, 4}, {"True", 2, 1}, {5}, {5, 6}, {7, 8, 9}};

Using SequenceSplit:

patt = {{"True", ___}, _, _};

DeleteCases[SequenceSplit[lis, s : patt :> s], Except[patt]]

(*{{{"True", 3, 4, 5}, {6, 5}, {3}}, {{"True", 2, 1}, {5}, {5, 6}}}*)

Or using ReplaceList:

ReplaceList[lis, {___, s : PatternSequence[Sequence @@ patt], ___} :> {s}]

(*{{{"True", 3, 4, 5}, {6, 5}, {3}}, {{"True", 2, 1}, {5}, {5, 6}}}*)
$\endgroup$
2
$\begingroup$
list = 
 {{1, 2, 3}, 
 {"True", 3, 4, 5}, {6, 5}, {3}, {6, 4}, 
 {"True", 2, 1}, {5}, {5, 6}, {7, 8, 9}};

Using SequencePosition and Take

p = SequencePosition[list, {{"True", ___}, _, _}]

{{2, 4}, {6, 8}}

Take[list, #] & /@ p

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

$\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.