I would like to make a sublist consisting of the four elements that follow each occurrence of 1, 2 in the list:
lis = {a, b, 1, 2, c, d, e, f, g, 1, 2, w, x, y , z, q, r}
to make:
res = {{c, d, e, f}, {w, x, y, z}}
Thanks for any thoughts.
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityCases[{2, p__} /; Length[{p}] >= 4 :> {p}[[;; 4]]] @
Rest @ Split[lis, {#, #2} =!= {1, 2} &]
{{c, d, e, f}, {w, x, y, z}}
And a variation:
Cases[{2, p__} /; Length[{p}] >= 4 :> Take[{p}, 4]] @
Rest @ Split[lis, {#, #2} =!= {1, 2} &]
{{c, d, e, f}, {w, x, y, z}}
lis = {2, a, b, f, h, 1, 2, c, d, e, f};
.
$\endgroup$
Aug 29, 2021 at 7:45
Split
with Rest
fixes the issue.
$\endgroup$
Rest
! Probably more efficient version: Cases[{2, p : Repeated[_, {4}], ___} :> {p}]@Rest@Split[lis, {#, #2} =!= {1, 2} &]
.
$\endgroup$
Aug 29, 2021 at 8:45
An alternative solution to @TumbiSapichu's one:
SequenceCases[lis, {1, 2, p : Repeated[_, {4}]} :> {p}]
(* {{c, d, e, f}, {w, x, y, z}} *)
Something like this?
res = #[[-4 ;;]] & /@ SequenceCases[lis, {1, 2, _, _, _, _}]
(*{{c, d, e, f}, {w, x, y, z}}*)
(lis // SequencePosition[#,{1,2}][[All,2]]& // {1 + #,4 + #}&// Transpose)
// Map[Take[lis,#]&]
(* {{c, d, e, f}, {w, x, y, z}} * )
lis[[# + 1 ;; # + 4]] & /@ (#[[2]] & /@ SequencePosition[lis, {1, 2}])
Using Partition
can assist in generating lists that have the correct length and need subsequent filtering only.
lis = {a, b, 1, 2, c, d, e, f, g, 1, 2, w, x, y, z, q, r};
Cases[Partition[lis, 6, 1], {1, 2, a__} :> {a}]
{{c, d, e, f}, {w, x, y, z}}
Consider a list (lis2
) with an overlap and less than 4 characters after 1,2
.
lis2 = {a, b, 1, 2, c, d, e, f, g, 1, 2, w, x, y, z, q, r, a, b, 1, 2, c, d, g, 1, 2, k, l, m, n, q, r};
Cases[Partition[lis2, 6, 1], {1, 2, a__} :> {a}]
{{c, d, e, f}, {w, x, y, z}, {c, d, g, 1}, {k, l, m, n}}
The third sublist can be filtered with an improved pattern that removes the overlap, if required.
Cases[Partition[lis2, 6, 1]
, {1, 2, b__ /; FreeQ[{b}, 1 | 2]} :> {b}]
{{c, d, e, f}, {w, x, y, z}, {k, l, m, n}}
Another way using Cases
and SequenceSplit
:
Cases[SequenceSplit[lis, Repeated[{1, 2}]], x_ /; Length[x] >= 4 :> x[[1 ;; 4]]]
{{c, d, e, f}, {w, x, y, z}}