10
$\begingroup$

I have a list from which I would like to extract sublists:

lis = {{a,X,b},{c,d,e,X,f},{h,j,X}}

giving:

res = {{a},{c,d,e},{h,j}}

i.e., deleting each X and its following elements from each sublist. Likely asked and answered; any pointers will be greatly appreciated!

$\endgroup$
1
  • 5
    $\begingroup$ you could make Thanks Listable and save yourself the /@ :D $\endgroup$
    – Sascha
    Oct 5, 2016 at 19:59

6 Answers 6

14
$\begingroup$

You can use ReplaceAll with an appropriate pattern in such cases

{{a, X, b}, {c, d, e, X, f}, {h, j, X}} /. {begin___, X, end___} :> {begin}

Note the use of named patterns of the BlankNullSequence variety that can stand for any sequence of zero or more expressions

$\endgroup$
1
  • $\begingroup$ This is one elegant answer! beautiful! $\endgroup$
    – alex
    Apr 16, 2023 at 10:34
13
$\begingroup$
lis = {{a, X, b}, {c, d, e, X, f}, {h, j, X}};
TakeWhile[#, # =!= X &] & /@ lis

{{a},{c,d,e},{h,j}}


From comment by Mr. J.M

First[Split[#, #2 =!= X &]] & /@ lis
$\endgroup$
3
  • 5
    $\begingroup$ In the same vein: First[Split[#, #2 =!= X &]] & /@ lis $\endgroup$ Oct 5, 2016 at 19:06
  • $\begingroup$ @J.M. Maybe it deserve as a answer. :) $\endgroup$
    – yode
    Oct 6, 2016 at 7:05
  • $\begingroup$ I'd prefer you edit your answer instead, as it is too similar to yours. $\endgroup$ Oct 6, 2016 at 7:20
11
$\begingroup$

Using Position

lis = {{a, X, b}, {c, d, e, X, f}, {h, j, X}};

#[[1 ;; Position[#, X][[1, 1]] - 1]] & /@ lis

(*  {{a}, {c, d, e}, {h, j}}  *)
$\endgroup$
1
  • 1
    $\begingroup$ It's worth noting that this one assumes that each sublist does contain an X. $\endgroup$ Oct 6, 2016 at 12:05
4
$\begingroup$

Using SequenceReplace:

lis = {{a, X, b}, {c, d, e, X, f}, {h, j, X}, {X, n, o}}

SequenceReplace[#, {a___, X, b___} :> a] & /@ lis

{{a}, {c, d, e}, {h, j}, {}}


If lists without an X need to be ignored, then it is better to execute:

DeleteCases[lis, _?(FreeQ[#, X] &)]

prior to running the modified list through the SequenceReplace command.

$\endgroup$
2
$\begingroup$
list = {{a, X, b}, {c, d, e, X, f}, {h, j, X}};

Map[SequenceSplit[#, {X}] &, list][[All, 1]]

{{a}, {c, d, e}, {h, j}}

MapThread[Take, {list, Position[list, X][[All, 2]] - 1}]

{{a}, {c, d, e}, {h, j}}

$\endgroup$
2
$\begingroup$

Another way using MapThread, Position and Span:

list = {{a, X, b}, {c, d, e, X, f}, {h, j, X}};

MapThread[#1[[#2]] &, {lis, Span[# - 1] & /@ Flatten[Position[#, X] & /@ lis]}]

(*{{a}, {c, d, e}, {h, j}}*)

Or using ReplaceList:

ReplaceList[#, {a___, X, b___} :> a] & /@ lis

(*{{a}, {c, d, e}, {h, j}}*)
$\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.