# Select pattern at the list sub-level

I want to get a list from a parent list (containing sub-lists of unequal length) using Cases and a matching pattern. The parent list is

data = {{x,y,z,a},{a,x^m,y^n},{a,b^m}, {a,x,b,c}}


I want to pick the matching patterns (x^_,y^_) from the sub-lists and keep them in a similar list format. Using Cases (at level spec 2), I could almost achieve that but unfortunately, it writes in a single list (instead of keeping the patterns in the same sub-list from where they belong). Eg,

Cases[data,Alternatives@@{x|x^_,y|y^_},2]


gives me

{x, y, x^m, y^n, x}


whereas, the output I want

{{x, y}, {x^m, y^n}, {}, {x}}


such that the final findings corresponding to the matched pattern result similar format (even if it is an empty sub-list).

• Suppose you Map[Cases[#,...yourpattern...]&,data] That should use Cases on each of your sublists and return the results from each of those as a list and then all those lists will be returned in an enclosing list.
– Bill
Mar 13, 2022 at 0:27

Just map the Cases expression over the list:

Cases[Alternatives[x | x^_ | y | y^_]] /@ data

• Alternatives is redundant, so: Cases[x | x^_ | y | y^_] /@ data Mar 14, 2022 at 20:04
• lol! I simplified the disjunction but then didn't discard the wrapper! Mar 14, 2022 at 20:09

Pick performs the sort of operation the OP seeks, but it can be rather tricky (to me).

Pick[
data,
data /. {(x | y)^_. -> True, Except[_List | List] -> False}]

(*  {{x, y}, {x^m, y^n}, {}, {x}}  *)


Note: It will pick all form at all levels.

To get everything down only to level 2:

level = 2;
data2 = {{x, y, z, a}, {a, x^m, y^n}, {a, b^m}, {a, x, b, c, {x^2}}};
Pick[data2,
Replace[data2, {(x | y)^_. -> True}, level] /.
Except[True | List | _List] -> False]

(*  {{x, y}, {x^m, y^n}, {}, {x, {}}}  *)

• Here's an example of its trickiness: Pick[data, data, (x | y)^_.] has a {1} instead of the {} in the output. Mar 13, 2022 at 1:36
• I like the improvement dot . :) Mar 22, 2022 at 12:54
data = {{x,y,z,a},{a,x^m,y^n},{a,b^m}, {a,x,b,c}}

DeleteCases[data, Except[x | x^_ | y | y^_], {2}]


{{x, y}, {x^m, y^n}, {}, {x}}

data = {{x, y, z, a}, {a, x^m, y^n}, {a, b^m}, {a, x, b, c}};


Define pattern

p = x | x^_ | y | y^_;


Using SequenceCases

Catenate @ SequenceCases[#, {p}] & /@ data


{{x, y}, {x^m, y^n}, {}, {x}}

Using SequenceSplit

Catenate @ SequenceSplit[#, {Except @ p}] & /@ data


{{x, y}, {x^m, y^n}, {}, {x}}

data = {{x, y, z, a}, {a, x^m, y^n}, {a, b^m}, {a, x, b, c}};

data2 = {{x, y, z, a}, {a, x^m, y^n}, {a, b^m}, {a, x, b, c, {x^2}}};


Define pattern:

p = x | x^_ | y | y^_;


Using SubsetReplace:

f = Activate@InternalCopyListStructure[#,
SubsetReplace[Flatten@#, {Except[p]} -> Inactive[Nothing]]] &;

f@data

(*{{x, y}, {x^m, y^n}, {}, {x}}*)

f@data2

(*{{x, y}, {x^m, y^n}, {}, {x, {x^2}}}*)
`